【问题标题】:Ruby - convert from symbol to variableRuby - 从符号转换为变量
【发布时间】:2009-10-06 17:52:00
【问题描述】:

如何在 def 中将 :obj 转换回名为 obj 的变量?

def foo(bar)
  bar.some_method_call
end

foo :obj

更新: 最终的代码比这更复杂,但是......

我喜欢能说出来

foo :obj  

而不是

foo obj  

我正在研究一些类似 DSL 的语法。而这一变化会让事情变得更清晰。

【问题讨论】:

  • 这是否意味着您的符号(在条形内表示)直接对应于实例变量?

标签: ruby metaprogramming


【解决方案1】:

在您的示例中,obj 是什么类型的变量?如果它是调用 foo 的作用域的局部变量,则无法从 foo 内部访问它,除非您将当前绑定作为第二个参数传递。

如果你想访问实例变量@obj,很简单:

def foo(bar)
  instance_variable_get("@#{bar}").length
end

@obj = "lala"
foo("obj") #=> 4

【讨论】:

    【解决方案2】:

    你可以使用 eval

    def foo(bar)
      eval(bar.to_s).some_method_call
    end
    

    【讨论】:

      【解决方案3】:

      这有点奇怪,但是如果你愿意传递一个空块(或者无论如何你要传递一个),你可以从块中获取绑定,然后调用 eval 并传递绑定:

      def foo(symbol, &block)
        binding = block.send(:binding)
      
        eval(symbol.to_s, binding)
      end
      
      var = 3
      
      puts foo(:var) {}
      

      这将打印 3。

      另外,ActiveSupport 显然有一个叫做 Binding.of_caller 的东西,你可以使用它,这样你就不必通过块,但我不知道它的效果如何。

      另一种方法是调用 foo 并将绑定传入:

      def foo(binding, symbol)
        eval(symbol.to_s, binding)
      end
      
      binding = self.send(:binding)
      var = 3
      
      puts foo(binding, :var)
      

      【讨论】:

        【解决方案4】:

        你是指变量还是访问器方法? Sepp2k 给出了实例变量的名称;供访问者使用

        def foo(bar)
          self.send(bar).some_method_call
        end
        

        【讨论】:

          【解决方案5】:

          你几乎肯定不能。该定义将无权访问调用范围的局部变量。如果您想更全面地解释您正在尝试做什么,我们也许可以提供一个有用的替代方案。

          【讨论】:

            猜你喜欢
            • 2015-12-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-02-10
            • 1970-01-01
            • 1970-01-01
            • 2019-11-11
            • 2013-11-15
            相关资源
            最近更新 更多