【问题标题】:Get value into Ruby code block without it being the last statement [duplicate]在不作为最后一条语句的情况下将值放入 Ruby 代码块 [重复]
【发布时间】:2013-10-23 09:29:24
【问题描述】:

我想从 Ruby 代码块中的 yield 返回一个值。换句话说,我想将阻塞内部的值传递给块本身。

def bar
    puts "in block"
    foo = 1
    # The next line is wrong, 
    # but this is just to show that I want to assign a value to foo
    foo = yield(foo)
    puts "done block #{foo}"
end

puts "start"
bar do |shoop|
    puts "doing other stuff"
    shoop = 2
    puts "doing more stuff"
    # The following commented-out line would work, 
    # but I would rather not force the programmer 
    # to always put a variable at the end
    #shoop
end
puts "done"

我希望看到的输出是:

start
in block
doing other stuff
doing more stuff
done block 2
done

有什么方法可以在不依赖 Ruby 块末尾的隐式返回值的情况下实现这一点?我相信这是可能的,因为我之前在Sinatra 代码块中看到过这种行为。

【问题讨论】:

    标签: ruby


    【解决方案1】:

    您可以使用实例变量隐式返回值,就像在 Rails 中所做的那样:

    def bar
      yield
      puts "The block has assigned @value to #{@value}"
    end
    
    bar do
      @value = 42
      nil # Do not return value intentionally
    end
    

    此代码输出:

    The block has assigned @value to 42
    

    更新

    另一个不错的选择是使用辅助方法,许多框架也这样做:

    def bar
      def render(value)
        @value = value
      end
    
      yield
      puts "The block has rendered #{@value}"
    end
    
    bar do
      render 42
      nil # Do not return value intentionally
    end
    

    此代码输出:

    The block has rendered 42
    

    更新 2

    请查看@Marek Lipka https://stackoverflow.com/a/19542149/203174 的重要补充

    【讨论】:

    • 我不知道辅助方法。感谢您的明确解释。
    【解决方案2】:

    我必须警告您,@Daniel Vartanov 的答案仅适用于方法中的 self 和方法调用范围相同的情况。否则,该块应该在方法中self的上下文中调用,即:

    def bar(&block)
      instance_eval(&block)
      puts "The block has assigned @value to #{@value}"
    end
    

    【讨论】:

    • 谢谢你,Marek,这是一个有价值的补充,我会插入你的答案的链接。
    【解决方案3】:

    可以滥用Object#tap

    bar do |shoop|
      puts "doing other stuff"
      2.tap do
        puts "doing more stuff"
      end
    end
    

    点击 yield 到块,但结果是被点击的对象(在本例中为 2)。

    这是一个有趣的技巧,有时也很有帮助,但一个简单的临时变量通常更简单易读。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-08
      • 1970-01-01
      • 2021-02-10
      • 1970-01-01
      • 2013-03-27
      • 2023-03-31
      • 2013-04-25
      相关资源
      最近更新 更多