如何在Ruby中将字符串固定到变量上,并将整个内容作为变量进行求值?

如何在Ruby中将字符串固定到变量上,并将整个内容作为变量进行求值?,ruby,variables,dynamic,Ruby,Variables,Dynamic,我有以下Ruby代码: module BigTime FOO1_MONEY_PIT = 500 FOO2_MONEY_PIT = 501 class LoseMoney @@SiteName = 'FOO1' @site_num = @@SiteName_MONEY_PIT def other_unimportant_stuff whatever end end end 所以,我在这里试图做的是设置SiteName,然后使用Si

我有以下Ruby代码:

module BigTime
  FOO1_MONEY_PIT = 500
  FOO2_MONEY_PIT = 501
  
  class LoseMoney
    @@SiteName = 'FOO1'
    @site_num = @@SiteName_MONEY_PIT
    def other_unimportant_stuff
      whatever
    end
  end
end
所以,我在这里试图做的是设置SiteName,然后使用SiteName并将其与字符串_MONEY_PIT组合,这样我就可以访问FOO1_MONEY_PIT并将其内容(在本例中为500)存储在@site_num中。当然,上面的代码不起作用,但一定有办法做到这一点


谢谢

如果要动态获取常量的值,可以使用:

module BigTime
FOO1\u MONEY\u PIT=500
FOO2\u MONEY\u PIT=501
阶级损失金钱
@@SiteName='FOO1'
@site_num=BigTime.const_get(:“{@SiteName}\u MONEY_PIT”)
结束
结束
在任何情况下,都不要使用
Kernel#eval
在任何情况下都是极其危险的,在这种情况下,攻击者甚至有可能控制部分参数

例如,如果用户可以选择站点的名称,并将其站点命名为
require'fileutils';rm_rf(“/”)
,那么Ruby将很高兴地对代码进行评估,就像您告诉它的那样

Kernel#eval
非常危险,您不应该养成在问题上抛出
eval
的习惯。这是一个非常专门的工具,只有在没有其他选项(扰流板警报:几乎总是有其他选项)的情况下才应该使用,并且只有在彻底的安全审查之后

请注意,无论是否使用
eval
,动态构造变量名本身已经是一种代码味道。它几乎总是指向某个地方的设计缺陷。通常,几乎可以保证用数据结构替换多个变量。例如,在这种情况下:

module BigTime
金钱坑={
‘FOO1’=>500,
‘FOO2’=>501,
}.别动
阶级损失金钱
@@SiteName='FOO1'
@site_num=MONEY_PITS[@@SiteName]
结束
结束

您可以对其进行重构,以便使用哈希来查找您的姓名,并使用getter方法来检索该姓名,以便于测试/验证。例如:

module BigTime
  MONEY_PITS       = { FOO1: 500, FOO2: 501 }
  MONEY_PIT_SUFFIX = '_MONEY_PIT'
  
  class LoseMoney
    @@site = :FOO1

    def initialize
      site_name
    end

    def site_name
      @site_name ||= '%d%s' % [MONEY_PITS[@@site], MONEY_PIT_SUFFIX]
    end
  end
end

BigTime::LoseMoney.new.site_name
#=> "500_MONEY_PIT"

这是可以做到的,但这很困难,需要一些元编程。最好使用散列。在第二个示例中,@site\u num在类定义时间之外无法访问
BigTime::LoseMoney.new.instance_variable_get:@site_num#=>nil
是的,OP就是这样设计的。谢谢你的答案,我已经按照你在上一个示例中提出的方法尝试过了,但似乎没有效果。但是,让我提供更多的信息。我实际上有一个数组,我正试图访问它,这可能会使事情复杂化。示例:`module BigTime SITE1=20个钱池[SITE1][:site\u num]=500个SITE2=40个钱池[SITE1][:site\u num]=501类LoseMoney@@SiteName='SITE1'@site\u num=MONEY\u PITS[@@SiteName][:site\u num]end end`@site\u num应设置为500,但@SiteName似乎解释不正确。抱歉,无法确定如何使评论格式良好。。。