我创建了以下简单类:
class Test
def initialize(a, b)
@a = a
@b = b
end
def test
puts @a
end
end
有没有办法用@a
替换self
?我每次尝试这样做时都收到错误:
undefined method `a'
我这样做的原因是因为我想用两个参数创建一个新对象,然后对这些参数进行操作,如:
d = MyObject('title', 'Author')
d.showAuthor
答案 0 :(得分:5)
class Test
attr_accessor :a,:b #creates methods a,b,a=,b= and @a and @b variables
def initialize(a, b)
self.a = a #calls a=
self.b = b #calls b=
end
def test
puts a #calls method a; self.a would do the same.
end
def self.[](a,b)
new(a,b)
end
end
这会让你放弃新的(但你必须把parens改成方括号)所以你可以打电话:
d=Test['dog','cat']
d.a #'dog'
答案 1 :(得分:2)
对于这些类,它可以完成并且实际上is done:Array,String,Integer,Float,Rational,Complex和Hash。如果您考虑同等重要的Test类(顺便说一句名字),请考虑:
class Test
def initialize(a, b)
@a = a
@b = b
end
def test
puts @a
end
end
module Kernel
def Test(*args)
Test.new(*args) #that's right, just call new anyway!
end
end
book = Test('title', 'Author')
book.test # => title
由于Kernel
模块由Object
继承,因此全局命名空间现在具有Test方法。除非你绝对需要,否则不要这样做。
答案 2 :(得分:1)
您需要定义加速器,您可以使用attr_*
:
class Foo
attr_accessor :a,:b
def initialize(a, b)
self.a = a
self.b = b
end
end
也不要在Ruby中使用camelCase
,有一个名称为
snake_case
snake_case
CapitalCamelCase
CAPITAL_SNAKE_CASE
答案 3 :(得分:1)
当您使用self.a
时,Ruby正在为a
所代表的类寻找方法self
,因此您得到一个未定义的方法错误(因为您没有定义一个名为a
)。您可能正在寻找:
class Test
attr_accessor :a, :b
def initialize(a, b)
self.a = a
self.b = b
end
def test
puts self.a # "puts a" would be adequate here since it's not ambiguous
end
end
答案 4 :(得分:1)
所以你需要从实例外部访问你的实例变量?你可以使用attr_accessor来做到这一点:
class Test
attr_accessor :a
attr_accessor :b
def initialize(a, b)
@a = a
@b = b
end
end
t = Test.new(:foo, :bar)
t.a
t.b
attr_accessor
让你们都读写实例变量。如果您只需要阅读它,则可以使用attr_reader
,如果您只需要更改它,则可以使用attr_writer
。
有关属性访问者的更多信息:https://stackoverflow.com/a/4371458/289219
答案 5 :(得分:1)
class MyClass
def initialize(title,author)
@title = title
@author = author
end
def showAuthor
@author
end
end
那会产生......
d = MyClass.new("Grapes of Wrath", "Steinbeck")
d.showAuthor
=> "Steinbeck"