我對 ruby?? 和 tbh 編程真的很陌生。我正在嘗試使用以下代碼,以便使用 switch case 對多種口味執行相同的操作,如下所示 -
def Icecream
...
...
Value = case flavors
when 'STRAWBERRY'
(shop.straw * 1000).round(5)
when 'CHOCOLATE'
(shop.choc * 1000).round(5)
when 'VANILLA'
(shop.van * 1000).round(5)
when 'MANGO'
(shop.man * 1000).round(5)
end
...
...
end
如何創建輔助方法來減少代碼重復?這可能是一個愚蠢的問題,但對學習真的很有幫助。提前致謝!
因此,shop.straw 為我提供了一個雙倍值,我將其乘以 1000 并四舍五入。
uj5u.com熱心網友回復:
我會做一些事情:將代碼提取到輔助方法中并使用哈希而不是 case 塊:
FLAVORS = {
'STRAWBERRY' => :straw, 'CHOCOLATE' => :choc, 'VANILLA' => :van, 'MANGO' => :man
}.freeze
def do_math(flavor)
(flavor * 1000).round(5)
end
通過這兩種準備,您可以像這樣設定值:
value = do_math(shop.public_send(FLAVORS[flavors]))
uj5u.com熱心網友回復:
moyeradon建議的方法也可以與另一個重構配對
value = calculation(shop.flavor_value(flavor))
Shop 有一個現在可以處理口味的方法
def flavor_value(flavor)
flavor_sym = flavor.downcase.to_sym
# Then call the desired logic to get the values being returned by the straw, chocolate, van, man methods here
end
這樣 Icecream 就不知道個別口味,并且隨著口味的變化,您不需要更新 Icecream。
uj5u.com熱心網友回復:
你可以做幾件事。最簡單的解決方案可能是采用“雙精度值”作為引數的解決方案,如下所示:
def calculation(flavor)
(flavor * 1000).round(5)
end
然后,您的案例陳述將是:
Value = case flavors
when 'STRAWBERRY'
calculation(shop.straw)
when 'CHOCOLATE'
calculation(shop.choc)
when 'VANILLA'
calculation(shop.van)
when 'MANGO'
calculation(shop.man)
end
如果需要,您可能可以進一步簡化它,但這是主要思想。
uj5u.com熱心網友回復:
spickermann對使用散列的想法是正確的,但public_send在我看來對于不必要的部分有點不妥。沒有必要將元編程引入這種情況。更簡潔的方法是將商店值直接放入散列中,這會洗掉符號和public_send步驟。
flavor_to_price = {
'STRAWBERRY' => shop.straw,
'CHOCOLATE' => shop.choc,
'VANILLA' => shop.van,
'MANGO' => shop.man
}
p (flavor_to_price[flavors] * 1000).round(5)
這是一個使用模型的完整示例Shop:
class Shop
attr_reader :straw, :choc, :van, :man
def initialize
@straw = 1 # made up prices
@choc = 2
@van = 3
@man = 4
end
end
shop = Shop.new
flavor_to_price = {
'STRAWBERRY' => shop.straw,
'CHOCOLATE' => shop.choc,
'VANILLA' => shop.van,
'MANGO' => shop.man
}
# called 'flavors' in your code, but singular makes more sense
flavor = 'MANGO'
p (flavor_to_price[flavor] * 1000).round(5) # => 4000
如果您不希望哈希與商店關聯或需要在運行時處理價格變化,另一個避免元編程的選項是使用函式:
def flavor_to_price(shop, flavor)
{
'STRAWBERRY' => shop.straw,
'CHOCOLATE' => shop.choc,
'VANILLA' => shop.van,
'MANGO' => shop.man
}.fetch flavor
end
flavor = 'MANGO'
shop = Shop.new
p (flavor_to_price(shop, flavor) * 1000).round(5) # => 4000
也就是說,您可能有一個或兩個潛在的設計問題。味道到價格的哈希值可能應該由類本身控制,而不是像SMAG所建議的那樣作為外部案例/開關/分支或資料結構存在。
當您只是列出名稱-價格關系時,類屬性并不能很好地替代散列映射。假設您有 200 種口味。那將是您想要以更接近 JSON 原語的形式表示的資料,例如字串 -> 數字哈希而不是類屬性。我不認為 4 種口味會有所不同。
相關性較低,但我會將價格設為整數而不是浮點數,后者存在精度問題。添加小數點用于顯示目的,而不是業務邏輯。
這一切都有些推測,因為您可能是其現有 API 的客戶Shop并且必然會使用其現有 API。
這里有幾個其他可供比較的選擇。如果您真的不想為上述基于函式的版本承擔哈希分配成本(可能是過早的優化),lambdas 是可能的:
# ...
flavor_to_price = {
'STRAWBERRY' => lambda {|shop| shop.straw},
'CHOCOLATE' => lambda {|shop| shop.choc},
'VANILLA' => lambda {|shop| shop.van},
'MANGO' => lambda {|shop| shop.man}
}
flavor = 'MANGO'
shop = Shop.new
p (flavor_to_price[flavor].(shop) * 1000).round(5) # => 4000
另一種選擇是對商店使用閉包,這樣我們每個商店只產生一次哈希分配:
def make_flavor_to_price_translator(shop)
prices = {
'STRAWBERRY' => shop.straw,
'CHOCOLATE' => shop.choc,
'VANILLA' => shop.van,
'MANGO' => shop.man
}
Proc.new {|flavor| prices.fetch flavor}
end
shop = Shop.new
flavor = 'MANGO'
flavor_to_price = make_flavor_to_price_translator(shop)
p (flavor_to_price[flavor] * 1000).round(5) # => 4000
上述兩種方法具有明顯的可讀性權衡,因此我不一定會在沒有更多背景關系的情況下推薦它們。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/536877.html
上一篇:RubyonRails:條件顯示
