【问题标题】:Ruby local variable scopeRuby 局部变量作用域
【发布时间】:2017-07-21 01:29:18
【问题描述】:

我正在为 ruby​​ 中的变量范围而苦苦挣扎。我的印象是局部变量可以通过它们下面的方法访问。查看以下代码,但我得到一个未定义的变量错误。

a = Array.new

def testing()
  a.push("test")
end

testing

使用全局变量就可以了,如何避免使用全局变量?

【问题讨论】:

    标签: ruby variables scope


    【解决方案1】:

    这里没什么好说的,除了 Ruby 中的局部变量只能在定义它们的范围内以及在该范围内定义的捕获它们的任何块(闭包)中访问。因为在 Ruby 中,与其他一些动态语言不同,方法不是闭包,它们不捕获局部变量。

    如果你尝试过,比如说:

    irb(main):001:0> a = 3
    => 3
    irb(main):002:0> define_method(:testing) do
    irb(main):003:1*   puts a
    irb(main):004:1> end
    => :testing
    irb(main):005:0> testing
    3
    

    它可以工作,因为代码在块中而不是方法中。

    【讨论】:

      【解决方案2】:

      您可以使用实例变量。任何名称以 @ 开头的变量都是实例变量,并且在定义它的类或方法中的任何位置都可用。例如,在 B 类中定义的变量 @A 将可用于 B 中的任何方法。

      【讨论】:

        【解决方案3】:
        2.3.3 :007 > def testing()
        2.3.3 :008?>   [].push("test")
        2.3.3 :009?>   end
         => :testing
        2.3.3 :010 > testing
         => ["test"]
        

        你不能让局部变量被它们下面的方法访问,你可以像@Linuxios的答案那样使用块,或者使用它容易工作的方式。

        【讨论】:

          【解决方案4】:

          top-level 中定义一个方法可能会很混乱。让我们将代码包装在一个类中:

          class Foo
            a = []
          
            def testing
              a << 'test'
            end
          end
          

          (我将Array.new 缩短为[]a.push(...) 缩短为a &lt;&lt; ...

          Foo#testing 可以通过以下方式调用:

          foo = Foo.new
          foo.testing
          #=> undefined local variable or method `a'
          

          显然,这不起作用。第一个aclass 主体范围内的局部变量,而第二个a 是实例方法内的局部变量。

          将变量初始化从类体中移到initialize方法中也不起作用,因为局部变量不是跨方法共享的:

          class Foo
            def initialize
              a = []         # <- one 'a'
            end
          
            def testing
              a << 'test'    # <- another 'a'
            end
          end
          

          要使其正常工作,您必须使用 实例变量

          class Foo
            def initialize
              @a = []
            end
          
            def testing
              @a << 'test'
            end
          end
          
          foo = Foo.new
          foo.testing
          #=> ["test"]
          
          foo.testing
          #=> ["test", "test"]
          

          【讨论】:

            猜你喜欢
            • 2016-08-23
            • 2011-12-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-03-13
            • 1970-01-01
            相关资源
            最近更新 更多