簡體   English   中英

如何將字符串附加到變量上並將整個事物作為 Ruby 中的變量進行評估?

[英]How do I tack a string onto a variable and evaluated the entire thing as a variable in Ruby?

我有以下 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#const_get

module BigTime
  FOO1_MONEY_PIT = 500
  FOO2_MONEY_PIT = 501
  
  class LoseMoney
    @@SiteName = 'FOO1'
    @site_num = BigTime.const_get(:"#{@@SiteName}_MONEY_PIT")
  end
end

,在任何情況下,使用Kernel#eval這一點。 Kernel#eval是在有絲毫的可能性,攻擊者可能能夠控制參數的部分任何情況極其危險。

例如,如果用戶可以選擇站點的名稱,並且他們將站點命名為require 'fileutils'; FileUtils.rm_rf('/') require 'fileutils'; FileUtils.rm_rf('/') ,那么 Ruby 會很高興地評估該代碼,就像您告訴它的那樣!

Kernel#eval是非常危險的,你應該進入的只是拋出一個習慣eval的一個問題。 這是一個非常專業的工具,只有在沒有其他選擇時才應該使用(劇透警告:幾乎總是有其他選擇),並且只有在經過徹底的安全審查之后才能使用。

請注意,無論您是否使用eval ,動態構造變量名本身已經是一種代碼異味。 它幾乎總是指向某處的設計缺陷。 一般來說,你幾乎可以保證用一個數據結構替換多個變量。 例如在這種情況下是這樣的:

module BigTime
  MONEY_PITS = {
    'FOO1' => 500,
    'FOO2' => 501,
  }.freeze
  
  class LoseMoney
    @@SiteName = 'FOO1'
    @site_num = MONEY_PITS[@@SiteName]
  end
end

您可以將其重構為使用 Hash 進行名稱查找,並使用 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"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM