【问题标题】:Code not evaluated in default argument value specification默认参数值规范中未评估的代码
【发布时间】:2014-12-27 04:50:51
【问题描述】:

(至少某种)Ruby 代码在方法的默认值规范中被接受和评估。在下面,评估"foo" * 3

def bar baz = "foo" * 3; baz end
bar # => "foofoofoo"

def bar baz: "foo" * 3; baz end
bar # => "foofoofoo"

但是,当我尝试在默认值描述中的某个范围内评估局部变量/方法时,该局部变量/方法是在词法范围下评估的:

MAIN = TOPLEVEL_BINDING.eval('self')
foo = 3

def bar baz = MAIN.instance_eval{foo}; end
bar # => undefined local variable or method `foo' for main:Object

def bar baz: MAIN.instance_eval{foo}; end
bar # => undefined local variable or method `foo' for main:Object
  • 为什么上面的foo 不在MAIN 范围内评估,而是在词法范围内评估?
  • 这似乎对在默认值描述中可以评估的 Ruby 表达式有一些限制。究竟可以放什么?

【问题讨论】:

    标签: ruby local-variables lexical-scope


    【解决方案1】:

    foomain 的局部变量。您从外部访问局部变量的尝试可能会缩短为:

    ▶ MAIN = TOPLEVEL_BINDING.eval('self')
    ▶ foo = 3
    ▶ MAIN.foo
    #⇒ NoMethodError: undefined method `foo' for main:Object
    

    此代码的类似物以不那么纠结的方式是:

    class A
      foo = 5
    end
    
    class B
      def a_foo
        A.new.foo
      end
    end
    
    ▶ B.new.a_foo
    #⇒ NoMethodError: undefined method `foo' for #<A:0x00000002293bd0>
    

    如果你想提供从 Universe 到本地变量的访问,你需要实现 getter

    def MAIN.foo ; 5 ; end
    def bar baz = MAIN.instance_eval{foo}; baz; end
    
    ▶ bar
    #⇒ 5
    

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 2010-11-24
      • 1970-01-01
      • 2019-09-20
      • 1970-01-01
      • 2020-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-11
      相关资源
      最近更新 更多