Ruby - 确保局部变量不会与方法名称冲突

Sau*_*nda 1 ruby mixins

我试图通过应用单一责任原则来减少我的胖模型.我正在将很多常用代码剔除到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
Run Code Online (Sandbox Code Playgroud)

如果"主机类"有一个名为" my_total=如何确保my_total变量完全在update_total方法范围内并且与周围环境完全无关" 的方法,则上面的代码片段会产生完全意想不到的后果?

saw*_*awa 8

只要局部变量和方法解释之间存在歧义,它就会被解释为局部变量.

但是,除了方法定义之外,局部变量将不可用,因此您无需担心"主机类"中的名称崩溃.您只需要在您的方法定义中担心它update_total.由于您在定义中使用了固定数量的局部变量,因此您应该能够知道要注意哪些变量.

1.局部变量和setter方法之间的歧义

如果你有这个:

variable_name =
Run Code Online (Sandbox Code Playgroud)

然后它将始终被解释为局部变量赋值.如果要引用该方法variable_name=,则需要使用明显的接收器和/或一对括号来消除它与局部变量的歧义,如下所示:

self.variable_name = foo
variable_name=(foo)
self.variable_name=(foo)
Run Code Online (Sandbox Code Playgroud)

2.局部变量和getter方法之间的歧义

如果你有:

variable_name
Run Code Online (Sandbox Code Playgroud)

并且范围中没有这样的局部变量,那么它将被解释为方法调用.如果范围中有这样的局部变量,那么它将被解释为局部变量.如果要在这种情况下调用该方法,则需要使用显式接收器和/或一对括号(如下所示)将其从局部变量中消除歧义:

self.variable_name
variable_name()
self.variable_name()
Run Code Online (Sandbox Code Playgroud)


Ser*_*sev 5

有些东西你没有告诉我们.在这种情况下,唯一的"无意义后果" my_total=是不调用该方法,因为my_total创建了本地var .

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
Run Code Online (Sandbox Code Playgroud)

如果您打算拨打设定者,请将其打开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
Run Code Online (Sandbox Code Playgroud)