【问题标题】:Why don't ruby methods have lexical scope?为什么 ruby​​ 方法没有词法范围?
【发布时间】:2022-04-07 12:34:04
【问题描述】:

例如

def test
    a = "a is for apple"
    def inner_method
        a = "something" # this will refer to a different "a"
    end

    inner_method
    puts a
end

这有什么原因吗?块具有词法范围,那么方法为什么不呢?这会解决吗?

【问题讨论】:

    标签: ruby closures


    【解决方案1】:

    这是因为 Ruby 的方法不是一流的对象(例如,它们在IO 中是这样的)。那么当你定义内部方法时,接收者是什么?大概是方法本身,或者绑定什么的,但是Ruby没有OO那么深。

    无论如何,我不清楚您希望在示例中发生什么,您是否希望它修改局部变量 a?如果是这样,proc 是方法的合适替代品。

    def test
      a = "a is for apple"
      inner_method = lambda do
        a = "something"
      end
    
      a # => "a is for apple"
      inner_method.call
      a # => "something"
    end
    
    test
    

    functional.rb”是这种编程风格的一个更奢侈的例子。

    而“lambda, proc, and Proc.new”是 Ruby 不同类型闭包的细分。

    【讨论】:

    • 当其他所有东西都有词法范围时,它似乎不合适。
    • “其他一切”?除了块,nothing 具有词法范围。不是方法体。不是阶级机构。不是模块主体。不是脚本主体。 是“不合适的”。
    • Scala 的方法也不是一流的对象,但内部方法关闭了它们周围方法的环境。 “内部方法”没有关闭其外部方法有一个更简单的原因:因为它不是“内部方法”。这是一个全局方法的定义。
    • 我不确定什么是全局方法。可能是Object 上的一个方法,但我认为我们无法看到足够的上下文来断定这是目标。有一些隐藏变量可以跟踪变量的定义位置。我想它叫cbase,基于this,但我没有去尝试验证。
    • class/def/module/etc 是添加在对象模型之上的关键字 DSL,而像 cbase 这样的东西只是为了支持它而存在。像这样的情况或 instance_evalinstance_exec 仅对解释器魔术有意义。但是 OP 的期望是合理的,如果方法是一流的对象(或 vars 的糖),这将像他们预期的那样工作。理解在这种情况下会发生什么的唯一方法是了解对象模型(方法存储在类中)和解释器实现细节(例如,期望它定义一个单例方法也是合理的)。跨度>
    猜你喜欢
    • 2014-08-26
    • 1970-01-01
    • 2017-12-22
    • 1970-01-01
    • 2013-02-13
    • 2012-02-24
    • 2021-01-04
    • 2013-07-28
    • 1970-01-01
    相关资源
    最近更新 更多