7つの言語7つの世界 第2章 Ruby 1-3 日目練習問題やってみました
の 7 つの言語の言語の雰囲気を味わえる本です。
- 作者: Bruce A. Tate,まつもとゆきひろ,田和勝
- 出版社/メーカー: オーム社
- 発売日: 2011/07/23
- メディア: 単行本(ソフトカバー)
- 購入: 9人 クリック: 230回
- この商品を含むブログ (65件) を見る
そこで、私の解答例を載せてみることにしました。今回は、第2章 Ruby を読んで、「試してみよう」をやってみました。個人の解答例で絶対正解というわけではありませんが、参考になれば幸いです。また、「こうすればもっといいよ」というご意見・コメントがあれば、大歓迎です。
1 日目 (p.18)
Emacs 上で inf-ruby から irb を利用しました。
- 文字列 “Hello, world” を出力する.
irb(main):001:0> puts 'Hello , World' Hello, World nil
irb(main):002:0> puts 'Hellow, Ruby.'.index('Ruby') 8 nil
- 自分の名前を 10 回出力する
irb(main):003:0> puts "id:passingloop\n" * 10 id:passingloop id:passingloop id:passingloop id:passingloop id:passingloop id:passingloop id:passingloop id:passingloop id:passingloop id:passingloop nil
- 文字列 “This is sentence number 1” の 1 を 10 までカウントアップしながら 10 回出力する.
irb(main):001:0> 1.upto(10) { |i| puts "This is sentence number #{i}" } This is sentence number 1 This is sentence number 2 This is sentence number 3 This is sentence number 4 This is sentence number 5 This is sentence number 6 This is sentence number 7 This is sentence number 8 This is sentence number 9 This is sentence number 10 1
- ファイルに格納されている Ruby のプログラムを実行する.
irb(main):002:0> load '~/Desktop/foo.rb' foo true
- プレイヤーに数字を選択してもらい,その数字が生成された乱数よりも大きいか小さいかを返す.
irb(main):003:0> puts gets.to_i > rand(10) ? 'high' : 'low' 5 high nil
2 日目
ひとつめ、
# 最初に,each だけを用いて,16 個の数値と 4 個の数値の配列の中身を同時に出力せよ. array16 = (1..16).to_a queue = [] array16.each do |i| queue << i next if queue.length < 4 puts queue.join(',') queue = [] end puts '-' * 20 # 次に,同じことを Enumerable の each_slice を用いて実行せよ. array16.each_slice(4) { |a| puts a.join(',') }
実行結果:
% ruby 2-1.rb 1,2,3,4 5,6,7,8 9,10,11,12 13,14,15,16 -------------------- 1,2,3,4 5,6,7,8 9,10,11,12 13,14,15,16
ふたつめ、
# Tree クラスは面白いクラスだったが,きれいなインタフェースを用いて # 新しいツリーを指定することはできなかった.そこで,initializer に # ハッシュと配列が入れ子になった構造体を指定できるようにせよ. class Tree def initialize(tree) tree = tree.to_a.first if tree.is_a?(Hash) @name = tree[0] @children = tree[1].map { |subtree| Tree.new(subtree) } end end # 具体的には次のツリーを指定できるようにしたい tree = { 'grandpa' => { 'dad' => { 'child 1' => [], 'child 2' => [] }, 'uncle' => { 'child3' => [], 'child4' => [] } } } p Tree.new(tree)
実行結果
% ruby 2-2.rb #<Tree:0x0000010086c5d0 @name="grandpa", @children=[#<Tree:0x0000010086c4e0 @name="dad", @children=[#<Tree:0x0000010086c440 @name="child 1", @children=[]>, #<Tree:0x0000010086c3c8 @name="child 2", @children=[]>]>, #<Tree:0x0000010086c350 @name="uncle", @children=[#<Tree:0x0000010086c2b0 @name="child3", @children=[]>, #<Tree:0x0000010086c238 @name="child4", @children=[]>]>]>
みっつめ、
#!/usr/bin/env ruby # ファイル内で,あるフレーズを含むすべての行を出力する簡単な grep を書け. # 簡単な正規表現でマッチングを行い,ファイルから行を読み出す必要がある # (この処理は Ruby では驚くほど簡単に書ける). # 必要なら行番号も出力してみるとよい. regexp = Regexp.compile(ARGV.shift) open(ARGV.shift).each_with_index do |line, i| next unless regexp =~ line puts "#{i}: #{line}" end
実行結果
% ./2-3.rb ee 2-2.rb 0: # Tree クラスは面白いクラスだったが,きれいなインタフェースを用いて 4: class Tree 5: def initialize(tree) 6: tree = tree.to_a.first if tree.is_a?(Hash) 7: @name = tree[0] 8: @children = tree[1].map { |subtree| Tree.new(subtree) } 14: tree = { 26: p Tree.new(tree)
3 日目 (p.33)
class CsvRow def initialize(headers, row) @headers = headers @row = row end def method_missing(name, *args) @row[@headers.index(name.to_s)] end end module ActsAsCsv def self.included(base) base.extend ClassMethods end module ClassMethods def acts_as_csv include InstanceMethods end end module InstanceMethods def each @csv_contents.each do |row| yield(CsvRow.new(@headers, row)) end end 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 attr_accessor :headers, :csv_contents def initialize read end end end class RubyCsv # no inheritance! You can mix it in include ActsAsCsv acts_as_csv include ActsAsCsv acts_as_csv end csv = RubyCsv.new csv.each {|row| puts row.one}
実行結果、
% ruby 3.rb lions