[英]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.