【问题标题】:Can I access the methods defined in an implicit Proc in a Ruby method?我可以在 Ruby 方法中访问隐式 Proc 中定义的方法吗?
【发布时间】:2020-11-16 09:58:39
【问题描述】:

假设我有以下代码:

def my_test(&fn)
    #code goes here
end

my_test {
    def my_cool_fn(a, b)
        a + b
    end
}

问题:是否有某种方法可以从my_test 的主体中访问由块定义并作为fn 传递给它的特定方法?†支持>

这是我尝试过的。我受到Struct 通常定义方式的启发:

Person = Struct.new(:name, :age) {
    def greet
        puts "Person #{name} says hello!"
    end
}
mike = Person.new("Mike", 37)
mike.greet

我知道可以通过以下方式使用它来实现类似于我想要的效果,但是,非常不雅。

def my_test(&fn)
    ex_struct = Struct.new(:dummy, &fn)
    instance = ex_struct.new
    puts "The result is: #{instance.my_cool_fn 3, 6}"
end

my_test {
    def my_cool_fn(a, b)
        a + b
    end
}

这将打印预期的The result is: 9。但是,这似乎有点 hacky,我想知道是否有更“正确”的方式来实现这个结果。

(† 出于我的目的,这个问题纯粹是假设性的,出于娱乐目的;我并没有试图解决更大的问题,只是想了解更多关于这种语言的信息。)

【问题讨论】:

    标签: ruby function methods proc


    【解决方案1】:

    Ruby 是一种面向对象的语言。每个方法都需要在某些东西(某个对象)上定义。您需要选择要定义该方法的位置。

    您可以通过评估块在当前定义的同一对象 my_test (main) 上定义它。

    def my_test(&fn)
      instance_eval(&fn)
    end
    
    my_test {
      def my_cool_fn(a, b)
        a + b
      end
    }
    
    my_cool_fn(1,2) #=> 3
    

    或者你可以使用一个新的类/模块(例如Struct)并像你一样在那里定义它。

    【讨论】:

    • instance_eval/instance_exec 确实很有趣——它们一定会在全球范围内泄漏范围吗?
    • 没有。 instance_eval 的当前范围是全局的 (main),因为这是定义 my_test 的地方,我们不封装 eval。如果要封装它,请在其周围创建一个胶囊。一个(匿名)类或模块并将其评估到那里而不是当前范围。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-13
    相关资源
    最近更新 更多