Best of Ruby Quiz 笔记之一:Mad Libs

       我想读《Best of Ruby Quiz》并实践里面的内容是熟悉ruby的一个好方法,那么让我从今天开始,每天都用ruby来quiz一下。    
        几点说明:1、我是ruby新手,一开始要从看人家的答案开始,不一定能够提供自己的解决方案,而且我写的有些东西可能是很粗浅的,也请大家不要见笑;2、笔记里面的问题都是我自己不明白的地方,希望并欢迎与大家交流;3、我的笔记主要针对书上给出的标准答案。
       
       闲言少叙,下面开始Quiz 1: Mad Libs
 
关键字:字符串 erb 模板处理 正则表达式
      
        这个quiz的意图应该是读取一个文件中的文本(说明:下列文本中的下划线和颜色都是我自己加的,是为了看起来清晰),例如:
I ((a verb, past tense)) to the sandwich shop across the street for lunch yesterday. I go there at least ((a number)) times a week.
将这段文本读出后,针对每对(())中的内容,提问,并获取用户输入,例如针对((a number)),提问“Give me a number ” ,并接受用户的输入,进行替换。处理完成后,上面的文本应该变为:
I walked to the sandwich shop across the street for lunch yesterday. I go there at least 9 times a week.

1、书中给出的解决方案是要使用Ruby的内建类库"erb",erb是一个进行类似于模板处理功能的类库。可以执行一段文本中用<%%>包起来或者是以%开头的Ruby代码。
require 'erb'
str = %{\
% 2.times do |i|
 This is line <%= i %>
%end
%% done}
ERB.new(str, 0, '%').run

运行结果是:
 This is line 0
 This is line 1
% done
2、$answers = Hash.new
这一句里面的$表示一个全局变量的标识。
看了Ruby这些日子,我觉得这门语言最繁琐的就是使用了那么多的符号,并且互相之间产生了那么多的组合,对于初学者来说,记录和使用他们,是要付出很大努力的。而且我觉得在敲入代码的时候,这么多符号也很麻烦。比如这个$,就是其中之一。
3、$answers[question]
answers是一个Hash,这样的调用方式,表示引用answers这个Hash中以question为key的对应的value
4、key = if question.sub!(/^\s*(.+?)\s*:\s*/, "") then $1 else nil end
上面的代码有两个目的,
 第一,将(.+?)中匹配得到的值赋予key;
 第二,对question字符串进行处理,去除掉第一个冒号之后的空格和冒号以及之前的字符
 例如:假定question = " a : b : c ",经过上述语句处理后,key = "a", 而question = "b : c "
5、unless ARGV.size == 1 and test(?e, ARGV[0])
● ARGV是一个包含命令行参数的数组。ARGV[0]是程序的第一个参数而不是程序名称。当前程序的名称位于全局变量$0中。
● test(?e, ARGV[0])
test test(cmd, file1 <, file2>)->obj
使用数值cmd在file1或file1和file2上执行各种测试。cmd为?e,表示如果file1存在,则为true。因此,上面的语句的含义为:
“除非只有一个命令行参数,并且存在该参数表示的文件,否则:”执行后面的语句
6、madlib = "\n#{File.basename(ARGV.first, '.madlib' ).tr('_' , ' ' )}\n\n" + File.read(ARGV.first)
● File.basename
File.basename(filename<, suffix>) -> string
返回给定文件名filename的最后一部分。如果有suffix参数,且它出现在filename的末位,则它将被删除。通过使用".*"可以去除任意扩展名。
File.basename("/home/gumby/work/ruby.rb")  -> "ruby.rb"
File.basename("/home/gumby/work/ruby.rb", ".*")  -> "ruby"
●ARGV.first
arr.first ->obj 或nil
arr.first(count) ->an_array
返回数组的第一个元素,或前count个元素。如果数组为空,第一种形式返回nil,而第二种形式返回一个空数组。
● tr(' _', ' ')
tr str.tr(from_string, to_string) ->string
返回str的一个拷贝,用to_string的相应字符替换from_string的字符。如果to_string的长度比from_string短,就会用to_string的最后一个字符来填充。这两个字符串可能都使用c1-c2表示法来表示字符的区间,同时from_string可能以一个^字符开始,表示除了这些给定字符之外的所有字符。
"hello".tr('aeiou', '*')   ->"h*ll*"
"hello".tr('^aeiou', '*')   ->"*e**o"
"hello".tr('el', 'ip')   ->"hippo"
"hello".tr('a-y', 'b-z')   ->"ifmmp"
综上,我认为上面这句的作用应该是将后缀为madlib的文件的文件名和文件的内容统一放在一个大字符串内
====================================================================================
上述6点,是我针对书上提供的标准解决方案的问题笔记。欢迎大家一起进行探讨。
MadLib标准解决方案

 

posted on 2007-07-17 10:54  小熊bryan  阅读(794)  评论(0编辑  收藏  举报