【问题标题】:Call property programmatically in Ruby [duplicate]在Ruby中以编程方式调用属性[重复]
【发布时间】:2017-04-04 12:16:00
【问题描述】:

我有一个 Ruby 项目,我在其中以编程方式获取我需要访问的哈希中的键名。我可以通过以下方式访问我需要的字段:

current_content = entry.fields[property_name.to_sym]

但是,有些内容似乎只能通过属性语法访问:

m.title_with_locales = {'en-US' => 'US Title', 'nl' => 'NL Title'}

由于我事先不知道“标题”,我如何以编程方式拨打电话?例如:

m.${property_name}_with_locales = {'en-US' => 'US Title', 'nl' => 'NL Title'}

【问题讨论】:

  • 请注意链接问题中public_send 的用法,除非您知道为什么这样做,否则切勿使用send

标签: ruby programmatically ruby-2.3


【解决方案1】:

您可以使用#send 以编程方式访问属性:

m.send("#{property_name}_with_locales")
# => { 'en-US' => 'US Title', ... }

如果你需要访问一个setter并传入值,你可以这样做:

m.send("#{property_name}_with_locales=", { 'whatever' => 'value' })

【讨论】:

    【解决方案2】:

    除了@gwcodes 所写的send,还有evalcall

    2.3.1 :010 > a
     => [1, 2, 3] 
    2.3.1 :011 > a.send("length")
     => 3 
    2.3.1 :012 > a.method("length").call
     => 3 
    2.3.1 :013 > eval "a.length"
     => 3 
    

    as shown on this blog post callsend 快一点。

    【讨论】:

    • 谨防旧基准 - 从 2008 年开始! :-) 这在 Ruby 的较新版本中并非如此,send 实际上应该更快(但我们在这里谈论的是微小的差异)
    • 对不起,我自己没有更新 -))
    • 永远不要使用eval,除非您绝对必须这样做并理解这样做的后果(即,如果有人设法注入意外的 ruby​​ 代码,则存在引入远程代码执行漏洞的危险)。
    • 此外,链接基准存在严重缺陷,因为使用a.method("length").call 的昂贵部分,即方法对象的生成,被排除在基准之外。如果将其包含在循环中,最快的选项将再次是 sendpublic_send
    猜你喜欢
    • 1970-01-01
    • 2011-02-26
    • 2021-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-01
    相关资源
    最近更新 更多