2011-08-11 31 views
2

我想以編程方式將新變量插入到本地Ruby命名空間中。例如,我希望能夠寫Ruby:將變量導入本地命名空間

label = 'some_name' 
# some code equivalent to 
# some_name = 3 
# but using only 'label' to get the name. 
puts some_name # returns 3 

我在這裏中間放置了什麼來完成這個任務?

+0

當你說符號時,我想你不是指Ruby中的符號,對(例如:a_symbol)?如果在代碼後面的行中沒有使用它,標籤究竟是什麼? – mikong

+0

@ mikong:謝謝,我澄清了這個問題。我希望'some_name'稍後在代碼中可用。你可以假設'label'只是知道調用變量的機制。 – Peter

+0

起初我以爲你應該只使用Ruby常量。但似乎你想要任意改變標籤,你的投標線只能改成新名稱,對嗎?確認後,我會稍微寫一下解決方案。 – mikong

回答

3

我已經回答了另一個SO question similar to this。簡單的答案是,如果你特別想創建一個局部變量,其名稱基於另一個變量的值,那麼就沒有辦法做到這一點。你只是想讓看起來像好像你創建了一個本地的,但它真的是紅寶石魔法,然後像@ mikong的答案是一種方式。

請注意,如果你放鬆你的禁忌並樂意創建一個實例變量,那麼你可以可以做到這一點。

label = 'some_name' 
self.instance_variable_set("#{label}", 3) 
puts @some_name 

你甚至可以動態定義的訪問,然後你就可以擺脫難看@的,但是再一次,您將只需僞裝成一個本地,而不是真正的局部變量的方法。

+0

對於'attr_reader'動態定義的+1。這讓我實現了我的目標。 – Peter

2
label = 'some_name' 
eval "#{label} = 3" 
puts eval "#{label}" 
puts local_variables 

注意,你大概從來沒有執行的機會...

puts some_name 

...因爲如果你知道你要創造就沒有必要什麼名字的局部變量他們與運行時代碼。這很好,因爲解釋器不會直接puts some_name,因爲它從未解析過some_name的賦值。但它那裏它一個地方,因爲puts local_variables是能夠顯示。

+0

有趣。代碼中的所有四行代碼都適用於ruby-1.8.7-p334。然而,如果我在ruby-1.9.2-p180中運行相同的程序,那麼'只將local_variables'輸出放在「label」和'puts eval「#{label}'會引發一個異常:'test.rb:3:'eval' :未定義的局部變量或方法'some_name'for main:Object(NameError)'。 –

+0

這是因爲在1.9中局部變量只能在定義它們的'eval'的上下文中使用,所以你在一個'eval '並嘗試在另一個內部使用它,你會得到......以及你得到的東西:) – skorks

+0

嗯,所以它可能是一個好主意,或者切換到創建實例變量而不是當地人,或者只是使用更多複雜的數據結構,所以你不需要動態地創建個人名字,很難看到通過簡單的Hash鍵創建Ruby級別的名字的好處(我試圖避免給*「不這樣做首先「建議,因爲有時動機是學術上的好奇心,但在這種情況下......) – DigitalRoss

2

以下是不完全的,你上面提到的兩行之間的代碼:

class Example 
    attr_accessor :label 

    def method_missing(name, *args, &block) 
    return some_processing if name == label.to_sym 
    end 

    def some_processing 
    3 # of course, this can be something more complicated 
    end 

    def test 
    @label = 'some_name' 
    puts some_name 
    end 

end 

但是它似乎與你所需要的工作。該機制已經從你給出的變化(標籤現在是一個屬性)。另外,從技術上講,它不是一個變量,而是一個具有動態名稱的方法,可以返回所需的內容。

就我個人而言,我認爲您的要求似乎有點危險,因爲「變量」的名稱發生了變化。我可能不會使用我的例子中的代碼。我想根據項目要求,我會想到一種不同的方法。