&tag(Ruby/ブロック); *目次 [#l257b861] #contents *参考情報 [#j06bf9b3] -[[Rubyで "&" を使うと幸せになれるらしいよ (*´Д`)ノ - (゚∀゚)o彡 sasata299's blog:http://blog.livedoor.jp/sasata299/archives/51382454.html]] *ブロックの呼び出し方 [#p4c0c681] -サンプルプログラム。Procに&をつけて渡すとブロックとして扱われる。引数に&をつけて受け取るとProcオブジェクトとして扱うことができる。 #pre{{ # 1. 普通のブロック 3.times do puts "hello1" end puts "" # 2. ブロックの中でProcを呼び出す proc = Proc.new {puts "hello2"} 3.times do proc.call end puts "" # 3. Procに&をつけて渡すとブロックとして扱われる 3.times(&proc) # 4. メソッドの仮引数に&をつけるとブロックをProcオブジェクトとして扱える def sample(&block) block.call('abc', 'def') end sample do |a, b| puts "#{a} #{b}" end }} -"&"を使った例。オブジェクトのメソッドが呼び出されている事がわかる。 #pre{{ class Person attr_accessor :name end p1 = Person.new p1.name = '田中' p2 = Person.new p2.name = '佐藤' p3 = Person.new p3.name = '鈴木' persons = [p1, p2, p3] p persons.map(&:name) # ["田中", "佐藤", "鈴木"] p persons.map(&:object_id) #[70144881868780, 70144881868740, 70144881868700] }} -mapに&つき引数が渡されている=Procオブジェクトが渡されていると期待されている(上記3番より)。そこで:nameや:object_idといったSymbolオブジェクトのto_procが暗黙的に呼び出されることになるらしい。 *ブロックの注意点 [#u8ec9410] -ブロックを抜ける場合returnを使わずnextを使った方がいい。 -returnを使うとブロックがメソッド内に存在する場合はそのメソッドが終了し、メソッド内に存在しない場合はLocalJumpErrorが発生する #pre{{ def message(comment) puts "message start comment=#{comment}" result = yield puts "message end result=#{result}" result end r = message('trueの場合') do true end puts "r=#{r}" # => true r = message('falseの場合') do false end puts "r=#{r}" # => false r = message('returnで抜ける場合') do i = 1 # if i == 1 # LocalJumpErrorとなる(メソッド内で呼ぶとそのメソッドが終わる) # return true # end if i == 1 next true end false end puts "r=#{r}" #=>true(nextに私た値) }}