【问题标题】:instance variable in blocks块中的实例变量
【发布时间】:2011-11-12 08:16:29
【问题描述】:

如何将实例变量作为参数传递给块?

这在 Ruby 1.9 中不起作用(形式参数不能是实例变量)。

awesome do |foo, @bar|
  puts 'yay'
end

【问题讨论】:

    标签: ruby


    【解决方案1】:

    Ruby 1.9 将块参数设置为块的本地参数。这也意味着块参数不能再是全局变量或实例变量。您可以将闭包用于您的目的:

    @foo = 10
    1.times do |i|
      puts @foo
    end
    # => "10"
    

    更新 局部变量可以帮助您,而不是使用实例变量:

    foo = 10
    1.times do |i|
      puts foo
    end
    # => "10"
    

    在这种情况下,您不会遇到与在不同上下文中执行代码相关的问题。

    【讨论】:

    • 我做不到。这就是为什么我很困惑!看看我的new question
    • 好的,知道了。我已经更新了我的帖子并回答了你的问题。
    【解决方案2】:

    这里有 3 种情况可能是相关的:

    • 引用实例变量的块的定义器的实例变量(在示例中使用awesome2
    • 块定义器的实例变量,将实例变量作为参数提供给接收器(没有机会将其作为参数提供给块)。这是awesome的用法。
    • 块用户的实例变量将实例变量作为参数提供给块。这是awesome3的用法。

    所以让我们尝试实现这两个示例以查看它们。例子很长,相关的几行是:

    • awesome 获取实例变量作为参数,然后由接收者在块调用中使用
    • awesome2 没有实例变量,它被Sender#use_in_block 绑定。接收方没有机会更改该绑定。
    • awesome3 获取发送者的实例变量,但使用自己的实例变量来调用块

    因此,根据您想要达到的目标,三者之一是更好的解决方案。

    class Sender
      attr_accessor :send_var
      def call_a_block(var)
        rec = Receiver.new(5)
        @my_var = var
        res = rec.awesome(@my_var) do |arg1|
          arg1 + 3
        end 
        res2 = rec.awesome3(@my_var) do |arg1|
          arg1 + 3
        end
        p "Result of calling awesome with: 3 and #{@my_var} is #{res}"
        p "Result of calling awesome3 with: 3 and #{@my_var} is #{res2}"
      end
      def use_in_block(var)
        rec = Receiver.new(6)
        @my_var = var
        res = rec.awesome2 do
          4 + @my_var
        end
        p "Result of calling awesome2 with: 4 and #{@my_var} is #{res}"
      end
    end
    
    class Receiver
      attr_accessor :rec_var
      def initialize(var)
        @rec_var = var
      end
      def awesome(arg1)
        res = yield(arg1)
        res * 2
      end
      def awesome3(arg1)
        res = yield(@rec_var)
        res * 2
      end
      def awesome2
        res = yield
        res * 2
      end
    end
    
    s = Sender.new
    s.call_a_block(7)
    s.call_a_block(20)
    s.use_in_block(7)
    s.use_in_block(20)
    

    结果是:

    c:\Temp>ruby call.rb
    
    "Result of calling awesome with: 3 and 7 is 20"
    "Result of calling awesome3 with: 3 and 7 is 16"
    "Result of calling awesome with: 3 and 20 is 46"
    "Result of calling awesome3 with: 3 and 20 is 16"
    "Result of calling awesome2 with: 4 and 7 is 22"
    "Result of calling awesome2 with: 4 and 20 is 48"
    

    【讨论】:

    • 感谢您的解释。其他人可能也想阅读此intro。我的问题不是这个,所以我问了一个新问题。
    • 另外,这是一个解决方案:[1,2,3].each {|bar| @bar=bar } 取自 here
    猜你喜欢
    • 1970-01-01
    • 2015-04-26
    • 1970-01-01
    • 1970-01-01
    • 2016-03-14
    • 1970-01-01
    • 1970-01-01
    • 2014-09-14
    • 1970-01-01
    相关资源
    最近更新 更多