我试图通过应用单一责任原则来减少我的胖模型。我正在将很多常用代码剔除到mixins中,然后将它们包含在多个类中。但是,我遇到了这个奇怪的局部变量问题,该问题与包含mixin的类的方法名称(或attr_accessors)发生冲突。例如:
module MyAwesomeMixin
def update_total
my_total = self.pricing_items.reduce(0) {|sum, x| sum + x} # this borks if the "host class" has a method called my_total=
total = my_total
end
end
如果“主机类”有一个名为my_total=
的方法,上面的代码段会产生意想不到的后果。如何确保my_total
变量完全在update_total
方法的范围内并且与周围的环境完全无关?
答案 0 :(得分:8)
每当局部变量和方法解释之间存在歧义时,它将始终被解释为局部变量。
但是,除了方法定义之外,局部变量将不可用,因此您无需担心“主机类”中的名称崩溃。您只需要在update_total
的方法定义中担心它。由于您在定义中使用了固定数量的局部变量,因此您应该能够知道要注意哪些变量。
<强> 1。局部变量和setter方法之间的歧义
如果你有这个:
variable_name =
然后它将始终被解释为局部变量赋值。如果你想引用方法variable_name=
,那么你需要通过使用公开接收器和/或一对括号来消除它与局部变量的歧义:
self.variable_name = foo
variable_name=(foo)
self.variable_name=(foo)
<强> 2。局部变量和getter方法之间的歧义
如果你有:
variable_name
并且范围中没有这样的局部变量,那么它将被解释为方法调用。如果范围中有这样的局部变量,那么它将被解释为局部变量。如果你想在这种条件下调用方法,你需要再次使用显式接收器和/或一对括号来消除它与局部变量的歧义:
self.variable_name
variable_name()
self.variable_name()
答案 1 :(得分:5)
有些东西你没有告诉我们。在这种情况下,唯一的“无意义后果”是不调用方法my_total=
,因为创建了局部变量my_total
。
module MyAwesomeMixin
def update_total
my_total = 10 # !> assigned but unused variable - my_total
end
end
class Foo
include MyAwesomeMixin
attr_accessor :my_total
end
f = Foo.new
f.my_total # => nil
f.update_total
f.my_total # => nil
如果您打算致电该二传手,请在self
上调用。
module MyAwesomeMixin
def update_total
self.my_total = 10
end
end
f = Foo.new
f.my_total # => nil
f.update_total
f.my_total # => 10