我想在Ruby中创建一个空数组作为类实例变量。但是,我目前的方法似乎不起作用。
这是我的代码:
class Something
@something = []
def dosomething
s = 5
@something << s
end
end
当我调用该函数时,它给了我一个未定义的方法回溯。 但是,如果我做类似于类变量的事情,即:
class Something
@@something = []
def dosomething
s = 5
@@something << s
end
end
这完美无缺。
我知道我可以使用initialize方法为@something实际创建一个空列表,但是有没有另外一种方法可以在不使用initialize方法的情况下执行此操作?为什么这对类变量有效?
编辑:修正了拼写错误
答案 0 :(得分:4)
你需要使用initialize作为构造函数,如下面的代码,是否有任何理由不使用initialize / constructor。请在课堂定义Class Something
中修正拼写错误class Something
在课堂上没有驼峰案例或首字母大写
class Something
def initialize
@something = Array.new
end
def dosomething
s = 5
@something << s
end
end
类变量@@
可用于整个类范围。所以他们正在使用代码,如果你想使用实例变量@,你需要像上面那样初始化它。实例变量与类
有关详细信息,请访问链接Ruby initialize method
答案 1 :(得分:2)
起初你有一个错字。将Class
更改为class
。接下来我建议使用initialize方法。在创建新对象时,这是初始化实例变量的理想位置。
class Something
@@my_class_variable = [1]
def initialize
@something = []
end
def dosomething
s = 5
@something << s
end
def self.get_my_class_variable
@@my_class_variable
end
end
您的脚本将从上到下阅读并执行,之后,
您可以访问课程Something
。当解析器读取您的脚本/类/模块时,您可以定义类变量(@@),执行mixins并使用其他模块扩展该类。这就是您可以定义类变量的原因,但您无法定义实例变量。因为实际上你的班级没有实例对象。你只有一个类对象。在红宝石中,一切都是一个对象。您的类对象现在有一个已定义的类变量:
Something.get_my_class_variable
# => [1]
现在您可以从班级创建实例。使用Something.new
将调用initialize方法,并定义您的实例变量。
something = Something.new
something.dosomething
# => [5]
稍后,如果您对此很熟悉,可以使用attr_reader
,attr_writer
和attr_accessor
来定义getter和setter方法,例如对象或cattr_reader
,{{1} }和cattr_writer
用于类对象。例如:
cattr_accessor
答案 2 :(得分:0)
尝试在实例方法中访问@something
时遇到的问题是,在实例方法的范围内,@
变量引用实例变量,而@something
是 class 实例变量。
@
变量是创建它们时self
的实例的实例变量。创建@something
时,self
是类Something
,而不是Something的实例,在实例方法中就是这种情况。
如何在实例方法中访问类实例变量?与常规实例变量一样,这必须通过方法完成,如attr_accessor
中所示。一种方法是使用class << self
告诉Ruby解释器应该用类(而不是实例)作为self来计算所包含的代码:
class C
@foo = 'hello'
class << self
attr_accessor :foo # this will be a class method
end
def test_foo # this is, of course, an instance method
puts self.class.foo # or puts C.foo
end
end
我们可以证明这适用于irb:
2.3.0 :005 > C.foo
=> "hello"
2.3.0 :006 > C.new.test_foo
hello
答案 3 :(得分:0)
您已正确创建了一个类实例变量@something
,并将其初始化为空数组。实例有两种方法来获取或更改该变量的值。一种是使用方法Object#instance_variable_get和Object#instance_variable_set(在类上调用):
class Something
@something = []
def dosomething
s = 5
self.class.instance_variable_get(:@something) << s
end
end
sthg = Something.new
sthg.dosomething
Something.instance_variable_get(:@something)
#=> 5
另一种方法是为变量创建一个访问器。有几种方法可以做到这一点。我的偏好如下:
Something.singleton_class.send(:attr_accessor, :something)
Something.something #=> [5]
在你的dosomething
方法中,你会写:
self.class.something << s