我正在尝试了解块以及yield它们在 Ruby 中的工作方式。
yield
如何yield使用?我看过的许多 Rails 应用程序都yield以一种奇怪的方式使用。
有人可以向我解释或告诉我去哪里了解他们吗?
是的,一开始有点令人费解。
在 Ruby 中,方法可以接收代码块以执行任意代码段。
当一个方法需要一个块时,您可以通过调用该yield函数来调用它。
例子:
拿Person,一个具有name属性和do_with_name方法的类。当方法被调用时,它会将name属性传递给块。
Person
name
do_with_name
class Person def initialize( name ) @name = name end def do_with_name # expects a block yield( @name ) # invoke the block and pass the `@name` attribute end end
现在您可以调用此方法并传递任意代码块。
person = Person.new("Oscar") # Invoking the method passing a block to print the value person.do_with_name do |value| puts "Got: #{value}" end
将打印:
Got: Oscar
请注意,该块接收一个名为 的变量作为参数value。当代码调用yield它作为参数传递的值@name。
value
@name
yield( @name )
可以使用不同的块调用相同的方法。
例如反转名称:
reversed_name = "" # Invoke the method passing a different block person.do_with_name do |value| reversed_name = value.reverse end puts reversed_name => "racsO"
其他更有趣的现实生活示例:
过滤数组中的元素:
days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"] # Select those which start with 'T' days.select do | item | item.match /^T/ end => ["Tuesday", "Thursday"]
或按名称长度排序:
days.sort do |x,y| x.size <=> y.size end => ["Monday", "Friday", "Tuesday", "Thursday", "Wednesday"]
如果该块是可选的,您可以使用:
yield(value) if block_given?
如果不是可选的,只需调用它。
irb您可以使用(交互式 Ruby Shell)在您的计算机上尝试这些示例
irb
以下是复制/粘贴就绪形式的所有示例:
class Person def initialize( name ) @name = name end def do_with_name # expects a block yield( @name ) # invoke the block and pass the `@name` attribute end end person = Person.new("Oscar") # Invoking the method passing a block to print the value person.do_with_name do |value| puts "Got: #{value}" end reversed_name = "" # Invoke the method passing a different block person.do_with_name do |value| reversed_name = value.reverse end puts reversed_name # Filter elements in an array: days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"] # Select those which start with 'T' days.select do | item | item.match /^T/ end # Sort by name length: days.sort do |x,y| x.size <=> y.size end