Skip to content

Instantly share code, notes, and snippets.

@jenny-codes
Created February 11, 2019 07:29
Show Gist options
  • Save jenny-codes/c44559594064c6e4270a7f68b95ab2ec to your computer and use it in GitHub Desktop.
Save jenny-codes/c44559594064c6e4270a7f68b95ab2ec to your computer and use it in GitHub Desktop.
# source: https://openhome.cc/Gossip/Ruby/Proc.html
# https://openhome.cc/Gossip/Ruby/IteratorBlock.html
# https://tonytonyjan.net/2011/08/12/ruby-block-proc-lambda/
# self-built reduce function
class Array
def my_reduce(value = 0)
for i in 0...self.length
value = yield(value, self[i])
end
value
end
end
# each do vs each {}:
# normal
puts [1, 2, 3].each { |element| print element }
# nothing printed, because it is received as 'puts ([1, 2, 3].each) do ...'
puts [1, 2, 3].each do |element|
print element
end
#
def def_without_block_in_param
yield if block_given? # not adding condition will cause 'LocalJumpError: no block given (yield)' when no block is given.
end
def def_with_amp(&block)
block.call # 'yield' works as well
end
def def_without_amp(block)
block.call
end
# proper usage
b = Proc.new { puts 'block here' }
def_with_amp(&b)
def_with_amp(&proc { puts 'block here' }) # proc == Proc.new
def_with_amp { puts 'block here' }
def_without_amp(b)
# 實際上,& 會觸發物件的 to_proc 方法
# 例如 Symbol 類別有直接定義 to_proc 方法:
["amazing_proc"].each { |name| name.capitalize! }
== :capitalize.to_proc.call("amazing_proc") # 先將 capitalize 變成 symbol, 再呼叫 to_proc 方法
== ["amazing_proc"].each(&:capitalize!)
# 如果不使用 symbol 的 to_proc 方法,可以在物件上面自己定義 to_proc,然後一樣用 & 來觸發
class Ball
attr_reader :radius
def initialize(radius)
@radius = radiu
end
def self.to_proc
Proc.new { |ball| ball.radius }
end
end
print [Ball.new(10), Ball.new(20), Ball.new(30)].collect(&Ball) # [10, 20, 30]
# Symbol 中的 to_proc 設計
class Symbol
def to_proc
Proc.new { |o| o.send(self) }
end
end
# Compare Proc with Lambda
def foo
f = Proc.new { return "return from foo from inside proc" }
f.call # control leaves foo here
return "return from foo"
end
def bar
f = lambda { return "return from lambda" }
f.call # control does not leave bar here
return "return from bar"
end
puts foo # prints "return from foo from inside proc"
puts bar # prints "return from bar"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment