我有一个类似于下面的类,我使用实例变量(数组)来避免使用很多方法参数.
这和我预想的一样,但这是一个好的做法吗?
class DummyClass
def self.dummy_method1
@arr = []
# Play with that array
end
def self.dummy_method2
# use @arr for something else
end
end
我有一个类似于下面的类,我使用实例变量(数组)来避免使用很多方法参数.
这和我预想的一样,但这是一个好的做法吗?
class DummyClass
def self.dummy_method1
@arr = []
# Play with that array
end
def self.dummy_method2
# use @arr for something else
end
end
在Ruby中,实例变量作用于类的原因是Ruby类本身有are个实例(类Class的实例).通过判断DummyClass.class
,自己try 一下.Ruby中没有C#意义上的"静态方法",因 for each 方法都在某个实例上定义(或继承到某个实例中),并在某个实例上调用.因此,它们可以访问被调用方上碰巧可用的任何实例变量.
因为DummyClass
是一个实例,所以它可以有自己的实例变量.你甚至可以访问这些实例变量,只要你有一个类的引用(这应该是因为类名是常量).在任何时候,您都可以调用::DummyClass.instance_variable_get(:@arr)
并获取该实例变量的当前值.
至于这是否是一件好事,it depends on the methods.
如果@arr
在逻辑上是实例/类DummyClass
的"状态",则将其存储在实例变量中.如果@arr
仅在dummy_method2
中用作操作快捷方式,则将其作为参数传递.举一个例子,在这里使用实例变量方法,考虑Rails中的ActureCordRD.它允许您执行以下操作:
u = User.new
u.name = "foobar"
u.save
在这里,已分配给用户的名称是用户合法拥有的数据.如果在拨打#save
之前,有人问"此时用户的名字是什么",你会回答"foobar".如果你深入研究内部(你会深入研究很多元编程,你会发现他们使用实例变量来实现这一点).
我使用的示例包含两个独立的公共调用.要了解尽管只进行了一次调用,但仍然使用实例变量的情况,请查看#update_attributes
的ActiveRecord实现.方法体就是load(attributes, false) && save
.为什么#save
没有通过任何参数(比如新的name
),即使它将在save where的主体中,比如UPDATE users SET name='foobar' WHERE id=1;
?这是因为像名字这样的东西是属于实例的信息.
相反,我们可以看看实例变量没有意义使用的情况.看看#link_to_if
的实现,它是一个接受布尔型实参(通常是源代码中的一个表达式)和#link_to
通常接受的实参(例如链接到的URL)的方法.当布尔条件为truthy时,它需要将其余参数传递给#link_to
并调用它.在这里分配实例变量没有多大意义,因为您不会说这里的调用上下文(渲染器)在实例中包含该信息.渲染器本身没有"链接到的URL",因此,不应将其隐藏在实例变量中.