本系列是《七周七语言》的课后习题答案。这本书不拘泥于语法细节,而是横向比较各种编程语言(非热门)之间的编程范式。
是本对编程觉悟能有所帮助的好书,这里就不多做介绍了,感兴趣的同学不妨去看一下。
不得不说,Ruby的风格很黑客。
1. 打印字符串"Hello, world."
puts "Hello, world."
2. 在字符串“Hello, Ruby.”中,找出"Ruby."所在下标。
puts "Hello, Ruby." =~ /Ruby/
3. 打印你的名字十遍
puts "angular "*10
4. 打印字符串"This is sentence number 1.", 其中的数字1会一直变化到10。
i = 1..10 i.each{|x| puts "This is sentence number #{x}.\n"}
5. 从文件运行Ruby程序
create test1.rb
write -> puts "hello\n"
save and exit
run -> ruby test1.rb
6. 让玩家猜随机数,并告诉玩家猜大还是猜小
guess.rb
input = gets rNum = rand(10) if(input.to_i > rNum) puts "bigger than #{rNum}" else puts "not bigger than #{rNum}" end
7. 分别找到用代码块和不用代码块读取文件的方法,用代码块有什么好处?
File.open("test.rb") do |file| file.each_line{|line| puts "Got #{line.dump}"} end
File.open("test.rb").each{|f| puts "Got #{f}" }
用代码块可以传递传递参数,做更多的操作。
8. 如何把散列表转换成数组
hash = { "a"=>["a", "b", "c"], "b"=>["b", "c"] }
可以用collect/map
hash.collect { |k, v| v } #returns [["a", "b", "c"], ["b", "c"]]
也可以用values
hash.values
9. ruby的数组可以做栈,还能用来做什么数据结构
可以用来作队列,链表,栈,集合等等。
10. 有一个数组,包含16个数字。仅用each方法打印数组中的内容,一次打印4个数字,然后,用可枚举模块的each_slice方法重新做一遍。
myArray = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] myArray.each do |a| if a % 4 == 0 print "#{a}\n" else print "#{a} " end end
require 'enumerator' myArray =[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] myArray.each_slice(4) {|a| p a}
11. 写一个可以接受散列表和数组嵌套结构的树类tree
12. 写一个简单的grep程序,把文件中出现某词组的的行权都打印出来。顺便加上行号。
puts "grep #{ARGV[0]};" File.open("e:/ruby/reg.txt") do |file| lnNum = 0 file.each_line do |ln| lnNum +=1 p "Line:#{lnNum} => #{ln}" if ln =~ /#{ARGV[0]}/ end end
13. 修改前面的CSV应用程序,使它可以用each方法返回CsvRow对象。然后,在CsvRow对象上,对某个给定标题,用method_missing方法返回标题所在的列的值。
比如,对于包含以下内容的文件:
one,two
lions,tigers
API可以像下面这样操作:
csv=RubyCsv.new
csv.each(|row| puts row.one)
这会打印出"lions"
module ActsAsCsv def self.included(base) base.extend ClassMethods end module ClassMethods def acts_as_csv include InstanceMethods end end module InstanceMethods def read @csv_contents = [] filename = self.class.to_s.downcase + '.txt' file = File.new(filename) @headers = file.gets.chomp.split(', ') file.each do |row| @csv_contents << row.chomp.split(', ') end end def each self.csv_contents.each do |row| i = CsvRow.new(row) yield i end end attr_accessor :headers, :csv_contents def initialize read end end end class CsvRow def initialize(row) @contents = row end def method_missing name, *args num = name.to_s if num == 'one' @contents[0] elsif num == 'two' @contents[1] end end end class RubyCsv include ActsAsCsv acts_as_csv end m = RubyCsv.new puts "Start...\n"; m.each do |row| puts row.one end puts "end...\n"
其中自定义了Csvrow类,重写了该类的method_missing方法,使得缺省的one/two方法可以成为参数灵活使用。
总结:
Ruby的开放类和模块(能写程序的程序),使得程序员可以把行为附加在语法上,这有别于传统的类继承。