Ruby bits 2 ( 1 ):BLOCKS, PROCS & LAMBDAS

1 minute read

雖然跟Ruby bit名字很像,但是內容的確比較進階點。

two ways for storing blocks

1.Proc

my_proc = Proc.new do
  puts "tweet"
end
my_proc.call # => tweet

等同於

my_proc = Proc.new { puts "tweet" }
my_proc.call # => tweet

2.lambda

使用lambda來儲存又稱為static lambda。

my_proc = lambda { puts "tweet" }
my_proc.call  # => tweet

Ruby1.9以前的版本是這樣寫

my_proc = -> { puts "tweet" }
my_proc.call  # => tweet

block to lambda

class Tweet
  def post
    if authenticate?(@user, @password)
      # submit the tweet
      yield
    else
      raise 'Auth Error'
    end
  end
end
tweet = Tweet.new('Ruby Bits!')
tweet.post { puts "Sent!" }

等同於

class Tweet
  def post(success)
    if authenticate?(@user, @password)
      # submit the tweet
      success.call
    else
      raise 'Auth Error'
    end
  end
end
tweet = Tweet.new('Ruby Bits!')
success = -> { puts "Sent!" }
tweet.post(success)

multiple lambdas

class Tweet
  def post(success, error)
    if authenticate?(@uerser, @password)
      # submit the tweet
      success.call
    else
      error.call
    end
  end
end
tweet = Tweet.new('Ruby Bits!')
success = -> { puts "Sent!" }
error = -> { raise 'Auth Error' }
tweet.post(success, error)

Using the ampersand

有兩種情況會用到ampersand也就是符號

1.Calling a method with & in front of a parameter

tweets.each(&printer)

turn a proc into block

2.Defining a method with & in front of a parameter

def each(&block)

turns a block into a proc so it can be assigned to parameter

這兩種用法很常同時使用

example 1:

printer = lambda { |tweet| puts tweet }
tweets.each (printer) (

這樣會出現錯誤,因為each expects a block, not a proc. 改成這樣就沒問題了。

printer = lambda { |tweet| puts tweet }
tweets.each(&printer)

&turns proc into block

example 2:

class Timeline
  attr_accessor :tweets
  def each(&block)       #block into proc
    tweets.each(&block)  #proc back into a block
  end
end
timeline = Timeline.new(tweets)
timeline.each do |tweet|
  puts tweet
end

symbol to Proc

未完待續…

Leave a Comment