Skip to content

Instantly share code, notes, and snippets.

@thash
Last active August 29, 2015 14:07
Show Gist options
  • Save thash/f5b8c4de506e2674fcdd to your computer and use it in GitHub Desktop.
Save thash/f5b8c4de506e2674fcdd to your computer and use it in GitHub Desktop.
AllAbout 021 Block
def iter(&b)
p b # => #<Proc:0x007fb92a934c30@ampersand.rb:6>
p b.class # => Proc
p b.class.ancestors # => [Proc, Object, Kernel, BasicObject]
# yieldの代わりにProc#callを使う
b.call # => hey
end
iter do
puts 'hey'
end
# lambdaで作成した手続きオブジェクト
l0 = lambda {|n, m| p n, m }
# 引数の数が間違っているとエラーになる
l0.call(1) #=> diff.rb:9:in `block in <main>': wrong number of arguments (1 for 2) (ArgumentError)
l0.call(1, 2, 3) #=> diff.rb:16:in `block in <main>': wrong number of arguments (3 for 2) (ArgumentError)
# procで作成した手続きオブジェクト
p0 = proc {|n, m| p n, m }
# 足りない引数をnilで埋め、
p0.call(1)
# => 1
# => nil
# 余分な引数は無視する
p0.call(1, 2, 3)
# => 1
# => 2
def check_block
if block_given?
puts 'block!'
yield
else
puts 'no block'
end
end
check_block # => no block
check_block { puts 'hello from block' }
# => block!
# => hello from block
x = 2
1.times do
puts x # => 2
end
pc = proc { x } #=> #<Proc:0x007fb333164818@closure.rb:10>
pc.call #=> 2
l = lambda { x } #=> #<Proc:0x007fb3331646b0@closure.rb:13 (lambda)>
l.call #=> 2
def hoge
x
end
hoge
#=> NameError: undefined local variable or method `x' for main:Object
# メソッドは定義時のローカル変数を参照できません
do
puts 'hoge'
end
#=> syntax error, unexpected keyword_do_block
#=> syntax error, unexpected keyword_end, expecting end-of-input
[1, 2, 3].each do |n|
puts n * 10
end
l0 = lambda do |n|
n * n
end
p l0.call(10) #=> 100
l1 = -> (n) { n * n }
p l1.call(20) # => 400
p Proc.new {}.lambda? #=> false
p proc {}.lambda? #=> false
p lambda {}.lambda? #=> true
p [1, 2, 3].map {|n| n ** n } #=> [1, 4, 27]
p [1, 2, 3].map do |n| n ** n end #=> #<Enumerator: [1, 2, 3]:map>
# do...endがmapの引数と認識されておらず、以下のように解釈されている
p [1, 2, 3].map #=> #<Enumerator: [1, 2, 3]:map>
# カッコで括り、map後のdo...endまで含めてpの引数であることを明示すれば意図通りに動く
p([1, 2, 3].map do |n| n ** n end) #=> [1, 4, 27]
pc0 = Proc.new do
puts 'in proc'
end
pc0.call # => in proc
pc1 = Proc.new do |n|
puts n * n
end
pc1.call(3) #=> 9
proc { puts 'hey' }
def wrap_lambda
l0 = lambda { return :lambda }
puts 'before call'
p l0.call
puts 'after call'
end
wrap_lambda
#=> before call
#=> :lambda
#=> after call
def wrap_proc
p0 = proc { return :proc }
puts 'before call'
p p0.call
puts 'after call'
end
wrap_proc
#=> before call
10.times do
puts 'hoge'
end
# => hoge
# => hoge
# => ... と10回表示する
def iter
puts '------------'
yield
puts '============'
end
iter do
puts 'hey'
end
#=> ------------
#=> hey
#=> ============
# 何回でもブロックを実行できます
def iter3
yield
yield
yield
end
iter3 do
puts 'fuga'
end
#=> fuga
#=> fuga
#=> fuga
iter #=> `iter': no block given (yield) (LocalJumpError)
def iter_with_args
puts '------------'
yield(10, 2) # yieldに引数を渡し、ブロック側で利用します
puts '============'
end
# yieldに渡されたブロック引数を参照します
iter_with_args do |n, m|
puts n * m
end
#=> ------------
#=> 20
#=> ============
def iter_with_args2(first, second)
yield first - 1, second + 1
end
iter_with_args2(10, 2) do |n, m|
puts n * m
end
# => 27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment