2014-09-05 16 views
0

對於我認爲可能是一個愚蠢的問題,提前道歉。我保證會搜索,但我不確定是否搜索了正確的內容。我是一個非常新的程序員,Ruby是我的第一個嚴肅的語言,在過去的幾個月裏我自學了它。我也從來沒有問過關於StackOverflow的問題,所以希望這是可以接受的清晰的,並滿足問題提出的其他要求。這裏是問題:設置一個字符串包含使用字符串時要檢查的變量 - Ruby 1.9.3

我有一個分支方法,根據傳遞給方法的值,調用各種不同的API和各種不同的URL。由於是,它看起來像:

if api == x 
url = "http://url.x.com/api/#{@variable}" 
elsif api == y 
url = "http://url.y.com/api/public/#{@var1}_#{@var2}/#{@variable}" 

URL的被稱爲是爲每個操作不同,因爲是必需的變量。請求中使用的變量在方法開始時被創建爲實例變量。實例變量的可能值存儲在大型散列中,或者由調用本身傳遞給方法。哈希的結構類似於:

$globalhash = 
{ 
"api_1" => 
{ 
"call_type_1" => {"info_1" => "", "info_2" => ""}, 
"call_type_2" => {"info_1" => "", "info_2" => ""} 
}, 
"api_2" => 
{ 
"call_type_1" => {"info_1" => "", "info_2" => ""}, 
"call_type_2" => {"info_1" => "", "info_2" => ""} 
} 
} 

我是這個分支部分繼續在代碼中很長一段時間的問題 - 部分原因是因爲我已經未達最佳的做了,我敢肯定。如果分支部分不存在,我也確信我的代碼會更高效。理想的情況下,而不是分支部分,我想做到這一點:

url = $globalhash[@api][@call_type]["url"] 

拉動將特定的呼叫類型和API的URL值 - 地址,格式和其他各種包括差異。所以一些值將是:

http://api.x.com/@[email protected]/@variable 
http://api.y.com/public/@variable 

等等。所以結構有所不同,我需要訪問方法調用中存儲的實例變量,但我需要動態執行。我遇到的問題是,我試圖實現這個結果的每個方法都會在程序開始運行時讀取$ globalhash時設置的「url」字符串中的實例變量的值,它們都是零。基本上,我需要它在請求發出時檢查變量,而不是之前。我在設置請求的post_data時遇到了類似(同樣的問題) - 如果我可以找到一種方法將它設置在哈希中,我會得到運行得更快的更簡潔的代碼。 post_data爲:

post_data = {'value' => @var1, 'value2' => @var2, 'value3' => @var3} 

等等。 post_data對於每個API和每個call_type都是不同的;值與它們的請求變量不同。我想實現一組中的散列鍵值對的,看起來像含糊:

$globalhash = {"api_1" => {"call_type_1" => {"url" => "http://api.x.com/#{@variable}", "post_data" => "{'value' => @var1, 'value2' => @var2, etc.}"}}} 

除,當然,這將需要努力 - 它需要引用變量是零的時候$ globalhash正在被閱讀。我不知道如何最好地解決這個問題。

該程序的工作原理是這樣,但我有一個很清晰的80行分支代碼,它們會計算出URL和post_data的結構,然後請求它。

我考慮的唯一解決方案是在方法中創建一個實例哈希以替換分支代碼,只有在聲明實例變量後才創建分支代碼。但是,我擔心會造成類似的問題,因爲每次創建一個巨大的新散列都效率低下。

感謝您的閱讀,我感謝您的幫助。我希望僞代碼是可以接受的,我發現它是解釋我的問題的最好方法。

編輯:找到一個解決方案。代碼:

url = eval "\"#{$globalhash["api_1"]["call_type_1"]["url"]}\"" 

[「網址」]引用「http://api.x.com/# {} @Variable」,單引號防止哈希內插值,eval函數將其放在雙引號和串插在它的時間收集實例變量調用。這是一個醜陋的方法,但它確實讓我大大縮短了我的代碼。來源:https://www.ruby-forum.com/topic/3237101

+0

這是相當困難的理解你的問題,雖然它可能是一個小問題。我建議重新修改它,或者總結一下你有什麼以及你需要/期望什麼。順便說一句。你可以用'Hash#has_key?'來檢查一個鍵是否存在,對於嵌套哈希來說,可以編寫一個輔助方法或者依靠'Hash#fetch'來處理'KeyError'異常。 – 2014-09-05 18:53:48

+0

tl; dr:我現在有一個80行分支if語句來計算出請求的url和post_data。我想取代它: URL = $ globalhash [@api] [@ CALL_TYPE] [ 「網址」] post_data = $ globalhash [@api] [@ CALL_TYPE] [ 「post_data」] 或類似的東西,但我無法弄清楚如何去做。我基本上想要一種方法來將包含變量的字符串存儲爲散列值,但我只希望它在引用它時檢查變量的值,而不是在最初讀取散列時。這是可能的,還是類似的可能性? – kerrai 2014-09-05 19:01:02

+0

你剛寫完了。創建一個像描述的嵌套哈希對象,並用'myhash.fetch(@api).fetch(@call_type).fetch('url')'和'rescue KeyError'獲取一個值。順便說一句。避免全局變量,除非你完全知道你在做什麼。 – 2014-09-05 19:10:14

回答

0

相反

post_data = {'value' => @var1, 'value2' => @var2, 'value3' => @var3} 

的使用實例變量創建哈希......你使用表示實例變量的字符串能夠初始化哈希值。

post_data = {'value' => '@var1', 'value2' => '@var2', 'value3' => '@var3'} 

然後,當您引用散列變量時,您會將該呼叫包裝在eval中。

post_data = {'value' => '@var1', 'value2' => '@var2', 'value3' => '@var3'} 

@var2 = 'this is test data' 

eval(post_data['value2']) 
=> "this is test data" 

同樣我會用佔位符網址...

url = 'http://api.x.com/[@variable]' 

@variable = "cotton_tree" 

my_url = url.dup 

my_url.sub!(/\[.*?\]/, eval(my_url.match(/\[(.*?)\]/)[1])) while my_url.match(/\[(.*?)\]/) 

p my_url 
=> "http://api.x.com/cotton_tree" 
相關問題