《七周7语言:理解多种编程范型》のruby课后习题答案

《七周七语言:理解多种编程范型》のruby课后习题答案

本系列是《七周七语言》的课后习题答案。这本书不拘泥于语法细节,而是横向比较各种编程语言(非热门)之间的编程范式。

是本对编程觉悟能有所帮助的好书,这里就不多做介绍了,感兴趣的同学不妨去看一下。

不得不说,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的开放类和模块(能写程序的程序),使得程序员可以把行为附加在语法上,这有别于传统的类继承。

1楼乱舞春秋
这本书还算是可以,只是还是有点侧重语法介绍,第一次看或许会有一些新鲜感的感觉(其实主要还是因为各种语言语法迥异),如果仔细回味回味啥啥也没有。
Re: 我读书少
@乱舞春秋,拿過來開闊眼界,或者作爲編程導論來看還行。