ruby - Ruby 中的 block 和产量

标签 ruby ruby-block

我正在尝试了解 block 和 yield 以及它们在 Ruby 中的工作方式。

如何使用yield?我看过的许多 Rails 应用程序都以一种奇怪的方式使用 yield

有人可以向我解释或告诉我去哪里了解它们吗?

最佳答案

是的,一开始有点费解。

在 Ruby 中,方法可以接收代码块以执行任意代码段。

当一个方法需要一个 block 时,您可以通过调用 yield 函数来调用它。

例子:

Person 为例,这是一个具有 name 属性和 do_with_name 方法的类。调用该方法时,它会将 name 属性传递给 block 。

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

请注意,该 block 接收一个名为 value 的变量作为参数。当代码调用 yield 时,它会将 @name 的值作为参数传递。

yield( @name )

可以用不同的 block 调用相同的方法。

例如反转名字:

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"]

如果该 block 是可选的,您可以使用:

yield(value) if block_given?

如果不是可选的,就调用它。

您可以在计算机上使用 irb ( Interactive Ruby Shell ) 尝试这些示例

以下是复制/粘贴形式的所有示例:

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

关于ruby - Ruby 中的 block 和产量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3066703/

相关文章:

ruby-on-rails - 在具有 yield 语句的 def 中使用 print

ruby-on-rails - Ruby on Rails 中的主页条件

ruby-on-rails - Rails 使用 block 渲染部分内容

ruby - 将 block 传递给映射函数

mysql - Chef ruby​​_block ShellOut mysql 结果 stdout 永远为空

ruby - 如何在 ruby​​ 中将 with_index 和 with_object 链接到可枚举对象上?

ruby - 为什么我不能用 yum 安装最新版本的 ruby​​?

ruby-on-rails - rails : How to get a model to "inherit" attributes from a parent model?

ruby - 如何从 Mechanize::Page 的搜索方法中获取 Mechanize 对象?

ruby - Nokogiri 用 <span>ed 词替换内部文本