ruby 在Ruby中传递块的教训

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ruby 在Ruby中传递块的教训相关的知识,希望对你有一定的参考价值。

# A Lesson in Passing Blocks in Ruby
# http://mudge.name/2011/01/26/passing-blocks-in-ruby-without-block.html

# FYI
# Do remember to actually check that a block was passed to the method with block_given?


# There are several main ways to receive blocks in a method in Ruby: the first is to use the yield keyword like so:
# Method 1 -- using yield
# It is clearly preferable to choose yield over &block
def speak
  puts yield
end
speak { "Hello" }
# => Hello


# Method 2 -- method signature with an ampersand method(&block) which will then create a Proc object
# The problem with the second approach is that instantiating a new Proc object incurs a surprisingly heavy performance penalty
def speak(&block)
  puts block.call
end
speak { "Hello" }
# => Hello

# Method 3 -- call Proc.new, this isn't removes the expense of Proc calling found in Method 2
def speak
  puts Proc.new.call
end
speak { "Hello" }
# => Hello


# What if you need to pass a block to another method?
# Example: here is a class that implements a method tell_ape which delegates to another, more generic method named tell

# Method 1
# My preference, cleaner. Downside: you can't look at the method signature to see if it takes a block
# you actually have to read more into the code
#  Upside: this has heigher performance than using &block
class Monkey
	def self.tell_ape
		tell("ape") {yield}
	end

	def self.tell(name)
		puts "#{name}: #{yield}"
	end
end
Monkey.tell_ape { "ook!" }
# => ape: ook!


class Monkey
  def self.tell_ape
    tell("ape", &Proc.new)
  end

  def self.tell(name)
    puts "#{name}: #{yield}"
  end
end
Monkey.tell_ape { "ook!" }
# => ape: ook!


class Monkey
  def self.tell_ape(&block)
    tell("ape", &block)
  end

  def self.tell(name, &block)
    puts "#{name}: #{block.call}"
  end
end
Monkey.tell_ape { "ook!" }
# => ape: ook!

以上是关于ruby 在Ruby中传递块的教训的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Ruby 中结束块的执行?

在 Vim 中注释/取消注释 ruby​​ 代码块的最优雅的方式是啥?

是否可以在 Ruby 中使用默认参数定义块?

ruby 用于理解Ruby块的代码。

Ruby:没有块的选择/查找有啥用吗?

Ruby 块的最佳解释? [关闭]