2014-05-15 58 views
0

如何从我的类实例中获取数据?我可以得到这个:无法从ruby中的类实例获取对象数据

instance = MyModule::MyClass.new(obj1, obj2) 

puts instance 
#=> #<MyModule::MyClass:0x0000010120de68> 

puts instance.inspect 
#=> #<MyModule::MyClass:0x000001019157b0 @obj1=#<MyModule::MyOtherClass:0x00000101915b20 @obj=["stuff", "more stuff", "things"]>, @obj2=#<MyModule::MyThirdClass:0x00000101915a80 @obj=["more things", "even more"]>> 

我以为我可以只是做instance.obj1并从这里得到@obj数组。这给了我“未定义的方法”。这里有什么问题?

回答

2

无法在默认情况下从外部访问的实例变量:

class Foo 
    def initialize(obj) 
    @obj = obj 
    end 
end 

foo = Foo.new(123) #<Foo:0x007fdc312205f0 @obj=123> 
foo.obj   # undefined method `obj' ... (NoMethodError) 

你必须创建一个getter这样做,例如通过attr_reader

class Foo 
    attr_reader :obj 

    def initialize(obj) 
    @obj = obj 
    end 
end 

foo = Foo.new(123) 
foo.obj   #=> 123 
+0

但我确实有访问者! – cheeseandpepper

+0

请发表相关的代码 – Stefan

+0

我想通了。涉及3个班级。将另外两个类作为参数的类有attr_accessors,但其他具有我想要公开的变量的类没有任何getter/setter。 – cheeseandpepper

0

你必须发布你的类定义给我们,以确定问题是什么,但我猜你没有为你的对象定义属性getters/setters。由于Ruby变量范围的工作方式,实例变量被本地化为对象实例的内部范围(这意味着它们只能在类定义中的方法定义中访问)。

为了从类定义的范围之外访问这些变量,必须定义属性getter和setter,与是暴露这些变量的外部范围的方法:

class Foo 
    def initialize(name) 
    @name = name 
    end 

    # attribute getter for @name 
    def name 
    @name 
    end 

    # attribute setter for @name 
    def name=(n) 
    @name = n 
    end 
end 

这是这样一个共同的图案Ruby已经为定义实例变量的设置者和获取者提供了辅助方法:attr_readerattr_writerattr_accessor

  • attr_reader采用一个或多个符号作为参数(其对应于要定位的实例变量),并创建吸气方法为每个。
  • attr_writer需要的符号相同的列表为attr_reader而造成二传手方法作为参数传递的每个实例变量名
  • attr_accessor同时生成二传手的getter方法命名实例变量。
class Bar 
    attr_reader :name # only allow reading of @name 
    attr_accessor :rank, :age # enable both reading and writing of @rank and @age 

    def initialize(name, rank, age) 
    @name = name 
    @rank = rank 
    @age = age 
    end 
end 

b = Bar.new('Jack BeLucky', 'Corporal', 32) 
b.name 
=> 'Jack BeLucky' 
b.age 
=> 32 
b.age += 1 
b.age 
=> 33