Chi*_*Kan 2 ruby methods ruby-on-rails
我有一些应该非常简单的东西,但这会让我感到害怕.
l = LineItem.first
#<LineItem id: 5, product_id: 1, quantity: 1, price: #<BigDecimal:7f7fdb51a3f8,'0.999E3',9(18)>, cart_id: 5, discount_percentage: 10, discount_amount: nil, discount_active: true, created_at: "2012-01-12 16:17:41", updated_at: "2012-01-12 16:17:41">
Run Code Online (Sandbox Code Playgroud)
我有
l.discount_percentage.blank?
=> false
Run Code Online (Sandbox Code Playgroud)
所以,我有以下方法:
def total_price
discount_amount = 0 if discount_amount.blank?
discount_percentage = 0 if discount_percentage.blank?
discounted_amount_from_percent = price*(discount_percentage.to_f/100)
applicable_discount = [discount_amount,discounted_amount_from_percent].max
return (price-applicable_discount)
end
Run Code Online (Sandbox Code Playgroud)
但是当我这样做时:
l.total_price
Run Code Online (Sandbox Code Playgroud)
而不是返回899,它返回999(意味着if discount_percentage.blank?根本不起作用!)
或者语法WHATEVER_HERE if true/false仅适用于View on Rails?
这里提出了一个问题:
discount_amount = 0 if discount_amount.blank?
discount_percentage = 0 if discount_percentage.blank?
Run Code Online (Sandbox Code Playgroud)
Ruby从上到下,从左到右"看到"变量,所以在该行中他首先看到一个局部变量(discount_amount =),所以他决定这个discount_amount东西discount_mount.blank?是同一个局部变量(而不是实例方法.你认为变量是尚未定义,但Ruby已经发现了它).没有任何值,discount_amount它设置为默认值nil,因此nil.blank?成功并进行分配discount_percentage = 0.同上discount_percentage.这是一个演示片段:
class ExampleClass
def run
x = "it works as expected" if x == "x"
x
end
def run2
if x == "x"
x = "it works as expected"
end
x
end
def run3
xy = "it works as expected" if x == "x"
xy
end
def x; "x"; end
end
p ExampleClass.new.run #=> nil
p ExampleClass.new.run2 #=> "it works as expected"
p ExampleClass.new.run3 #=> "it works as expected"
Run Code Online (Sandbox Code Playgroud)
步骤1:不要对局部变量和实例方法使用相同的名称.这通常是一个坏主意,因为你忘记了你正在使用哪一个,但在这种情况下,它真的咬了你.
第2步:在进行数学计算时不要编写命令式代码!实际上,数学(在典型应用中你做的事情的9X%,(10-X)%是不可避免的副作用)与表达一起使用,而不是用语句.我写道:
def total_price
final_discount_amount = discount_amount || 0
final_discount_percentage = discount_percentage || 0
discounted_amount_from_percent = price * (final_discount_percentage.to_f/100)
applicable_discount = [final_discount_amount, discounted_amount_from_percent].max
price - applicable_discount
end
Run Code Online (Sandbox Code Playgroud)