锁定老帖子 主题:Ruby Quiz
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2006-04-12
Quiz 1: MadLibs 简单的模板,假设有一句话 I had a ((an adjective)) sandwich for lunch today. It dripped all over my ((a body part)) and ((a noun)). 程序应该拿这些((..))中间的词组问你: Give me an adjective? Give me a body part? Give me a noun? 你回答以后,程序用你的答案代替相应的问题 譬如你分别回答smelly、big toe 、 bathtub 程序打印: I had a smelly sandwich for lunch today. It dripped all over my big toe and bathtub. 有时候你可能要重用问题,则可以给问题一个名字。例如: Our favorite language is ((gem:a gemstone)). We think ((gem)) is better than ((a gemstone)). 这里第一个((gem:a gemstone))给出了一个名字gem,而第二个((gem))直接用gem这个名字就可以复用第一个问题的答案了。 因此,程序只需要问你两个问题: Give me a gemstone? Give me a gemstone? 如果你回答 Ruby、Emerald 结果就是 Our favorite language is Ruby. We think Ruby is better than Emerald. 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2006-04-12
我自己做的答案按部就班,和他书上的第二个差不多,但是看起来还是比较Java。书上给的第三个答案比较有意思,一共6行代码
1 keys=Hash.new { |h, k| 2 puts "Give me #{k.sub(/\A([^:]+);:/, "");}:" 3 h[$1]=$stdin.gets.chomp 4 } 5 puts "", $*[0].split(".");[0].gsub("_", " ");, 6 IO.read($*[0]);.gsub(/\(\(([^);]+);\);\);/); { keys[$1] } 实际上,第4行的}不能算有效代码,而第5行是打印一个题头,真正有效的代码是4行 |
|
返回顶楼 | |
发表时间:2006-04-12
第5行开始的puts就是打印,它可以带n个参数,第一个参数""没啥用,第二个参数
$*[0].split(".");[0].gsub("_", " "); 中的$*实际上就是ARGV,$*[0]就是第0个参数split(".")把文件名和后缀名分开,然后gsub替换"_"为"",例如你的文件名为read_me.txt,就变成了read me.这句话就是打印一个题头。 IO.read($*[0]);.gsub(/\(\(([^);]+);\);\);/); { keys[$1] } 首先read($*[0])就是把命令行的第0个参数作为文件名,并把它的内容读入到一个字符串。gsub是全局替换,这里有两个参数 /\(\(([^);]+);\);\);/是它的正则表达式参数 keys[$1]是它的block参数 意思就是用正则表达式匹配,并每次用block返回的值进行替换。 /\(\(([^);]+);\);\);/的左边\(\(和右边\)\),分别匹配题意中的((..)),而([^)]+)则是一个group,匹配任何非)的字符,每次匹配成功((...))中间的内容变成$1,就是第一个group。 引用 keys[$1]
把$1作为关键字,去取它的值 现在看看 1keys=Hash.new { |h, k| 2 puts "Give me #{k.sub(/\A([^:]+);:/, "");}:" 3 h[$1]=$stdin.gets.chomp 4} Ruby的Hash构造函数有三种形式,这种方式是Hash.new block。此时,如果你用一个已经在Hash中存在的关键字去取值,那么就直接返回值,如果这个关键字不存在,那么就用hash本身和你需要的关键字调用这个block. 现在可以看看,如果没有答案的重用,例如 引用 I had a ((an adjective)) sandwich for lunch today. It dripped all
over my ((a body part)) and ((a noun)). 第一次用an adjective变成$1到keys去取值,没有找到,调用这个block,而且第2行的/\A([^:]+):/ 没有匹配,因此$1还是等于an adjective,结果就是屏幕提问 引用 Give me an adjective?
keys["an adjective"] = 你回答的答案 如果有可以重用的答案,例如: 引用 Our favorite language is ((gem:a gemstone)). We think ((gem)) is
better than ((a gemstone)). 第一次,$1="gem:a gemstone",显然无法在keys里面找到,但是第2行的/\A([^:]+):/匹配gem:,并且把$1="gem",因此,屏幕提示 引用 Give me a gemstone?
keys["gem"] = 你回答的答案 第二次,$1="gem",我们上一次已经在keys这个hashmap里面有了这个值,因此整个block就不执行,屏幕不需要提示,答案也可以重用了 |
|
返回顶楼 | |
发表时间:2006-04-12
这本书确实很不错
很多问题只需跳一跳自己也可以解 然后再看看解答 真的爽快 有时候读源码相对高度就会比较高 这个就比较好 |
|
返回顶楼 | |
发表时间:2006-04-12
我现在也在翻这本书,感觉真的不错。相对而言,算是比较高阶的了!很多的Quiz,在自己实际的implement以后,才发现别人的更高,实现的更加优雅!
也知道了自己的差距又多远... |
|
返回顶楼 | |
发表时间:2006-04-12
怎么感觉又想起了perl.
问题是,代码写成这样,简洁是简洁了,但是一般人猛一看,还真不知道它是干嘛的.想改个东西也不好下手. |
|
返回顶楼 | |
发表时间:2006-04-12
可能是$*和正则表达式给搞的吧
这个解答从某些方面来说并不是很好,譬如可读性方面,可重用性方面,只不过设计巧妙,充分利用了Block的优势 |
|
返回顶楼 | |
发表时间:2006-04-12
我同事的Javascript实现
<script> var str = "I had a ((gem:an adjective);); sandwich for lunch today. It dripped all over my ((gem);); and ((a noun););. "; /**** Start ****/ var h = {};// it's a Hash document.write(str.replace(/\(\(([^);]+);\);\);/ig,function($1,$2);{ var k = $2.split(":");[0],o=$2.split(":");[1]||k; return "<b style='color:red'>"+ (h[k]||(h[k]=prompt("Give me "+o,"");););+"</b>"; }););; </script> |
|
返回顶楼 | |
发表时间:2006-04-13
有没有类似的quiz书,在关于好的OOP方面的书推荐一下?
|
|
返回顶楼 | |
发表时间:2006-04-13
脚本语言可以写出十分灵活的代码。可它比较难懂
|
|
返回顶楼 | |