tsucchi’s diary(元はてなダイアリー)

はてなダイアリー(d.hatena.ne.jp/tsucchi1022)から移行したものです

「初めての Ruby」一人勉強会 8日目

Ruby をぼちぼち勉強しています。

教材はコレ↓
初めてのRuby


今日は第7章。メソッド

これを読みつつ、つぶやいてみます。

以下、つぶやきメモ。

※1 今のところ、正直あまり Ruby は好きではありません。
※2 オイラがまともにそこそこ書ける言語は C#, Java(5.0より前), Perl です。言語の機能を語っているときはその辺との比較になっているはず
※3 Ruby はまだほとんど理解していないので、的外れでトンチンカンな批判してるかも
※4 コードはサンプルそのままのときと、オイラが勝手に変えてるときがあります

引数は配列じゃないよ (p.129 例7-4)

可変長引数をサポートするけど、Perl みたいに引数を配列で受けるわけではないみたい。まあどちらかと言うと Perl がおかしいのだろうけど。

% irb
irb(main):001:0> def some_method(a, b)
irb(main):002:1> p [a, b]
irb(main):003:1> end
=> nil
irb(main):004:0> params = [1, 2]
=> [1, 2]
irb(main):005:0> some_method(params)
ArgumentError: wrong number of arguments (1 for 2)
        from (irb):5:in `some_method'
        from (irb):5
        from :0
void なメソッド(p.131 コラム 例7-9)

戻り値が無い場合は nil を返すのが ruby 流みたい。戻り値なしの return でも文法上は良いはずだけどね。

def black_box_process(x, y)
  # 何かの処理
  @c = a + b # この処理を外部に出したくない
  nil        # この nil があるので↑の処理結果が返らない
クロージャー (p.135 例7-15)
% irb
irb(main):001:0> def create_counter
irb(main):002:1> count = 1
irb(main):003:1> return Proc.new do
irb(main):004:2* count += 1
irb(main):005:2> p count
irb(main):006:2> end
irb(main):007:1> end
=> nil
irb(main):010:0> p counter.class
Proc
=> nil
irb(main):011:0> counter.call
2
=> nil
irb(main):012:0> counter.call
3
=> nil

クロージャーです。何となく分かってはいるのだけど、いまいち使い道が思い付かないのがクロージャーです。

ブロック付きメソッドを定義する(p.138-139 例7-24, 7-25)
]% irb
irb(main):001:0> def foo_bar_baz
irb(main):002:1> yield "foo"
irb(main):003:1> yield "bar"
irb(main):004:1> yield "baz"
irb(main):005:1> end
=> nil
irb(main):006:0> def foo_bar_baz2
irb(main):007:1> %w[ foo bar baz ].each do |item|
irb(main):008:2* yield item
irb(main):009:2> end
irb(main):010:1> end
=> nil
irb(main):011:0> foo_bar_baz do |item|
irb(main):012:1* puts item
irb(main):013:1> end
foo
bar
baz
=> nil
irb(main):014:0> foo_bar_baz2 do |item|
irb(main):015:1* puts item
irb(main):016:1> end
foo
bar
baz
=> ["foo", "bar", "baz"]

自前でブロック付きメソッドを定義する方法。yield という構文を使う。コールバックの一種だよね。うーん、何となく理解はしたけど、ちゃんと使える自信は無いなぁ。

ブロックをメソッドに渡す (p.140, 例7-28)
#!/usr/local/bin/ruby

class SleepyPerson
  def register_handler(&handler)
    @event_handler = handler
  end

  def wake_up!
    @event_handler.call Time.now, "woke up"
  end
end

john = SleepyPerson.new
john.register_handler{ |time, message| p [time, message] }
john.wake_up!

&をメソッドの仮引数に付けるとブロックを渡せるらしい。とりあえず例を写経してみたけど、あんまりちゃんと理解できてない。


「え゛ーーー」と思う事があんまり無かったけど、ブロック付きメソッドはあんまり理解できてないや。ruby 以外の言語に無い概念だもんなぁ。理解は浅い気がしますが、とりあえずおしまい。

8章に続く(多分)