如何在另一个类中访问一个类中的实例变量

时间:2009-02-28 08:26:16

标签: ruby instance-variables

我是Ruby的新手。新的 - 不到16个小时,但我的老板给了我一些Ruby代码添加。但是,我发现它是一个巨大的文件,根本不是模块化的,所以我决定清理它。现在我把它分成几个文件/类(一般来说,每个文件一个类),我遇到了拼凑它的问题让它再次工作。最初一切都是同一个班级的一部分,所以这些电话都有效,但它看起来很丑陋,整整一个工作日只是想弄明白。我希望将来避免这种情况,因为此代码在完成之前会变得更大。

我的主要问题如下(简化,显然):

class TestDevice   
   def initialize  
    @loghash = { }  
    ....  
   end  
end   

class Log  
    def self.msg(identifier, level, section, message)  
     ...  
     @loghash[identifier] = { level => { section => message }}  
     ...  
    end  
end  

device = TestDevice.new

之后,它调用其他类方法,并且这些类方法引用回Log类以了解其日志记录需求。当然,Log需要以某种方式访问​​“device.loghash”以记录该哈希中的信息。但我无法弄清楚如何在将“loghash”的内容传递给每个方法之外发生这种情况,以便它们反过来可以传递它,然后将值返回到原始点然后记录它最后,但这看起来非常笨拙和尴尬。

我希望我真的只是错过了一些东西。

3 个答案:

答案 0 :(得分:4)

要以简单的方式为实例变量创建访问器,请使用attr_accessor

class TestDevice   
  attr_accessor :loghash

  def initialize  
    @loghash = { }  
    ....  
  end  
end   

您也可以手动定义访问者。

class TestDevice
  def loghash
    @loghash
  end
  def loghash=(val)
    @loghash = val
  end
end

这实际上是attr_accessor在幕后所做的事情。

答案 1 :(得分:2)

如何将设备对象作为参数传递给msg函数? (我假设你的程序中可以有很多设备,否则你可以使用单例模式)。

class TestDevice   
   attr_accessor :loghash

   def initialize  
    @loghash = { }  
    ....  
   end  
end   

class Log  
    def self.msg(device, identifier, level, section, message)  
     ...  
     device.loghash[identifier] = { level => { section => message }}  
     ...  
    end  
end  

答案 2 :(得分:1)

所以你需要学习红宝石范围的规则。

Ruby变量具有不同的范围,具体取决于它们的前缀:

  • $global_variables$开头,并且每个人都可以使用。
  • @instance_variables以单个@开头,并以当前值self存储。如果两个 范围共享self的相同值(例如,它们都是实例方法), 然后两者共享相同的实例变量
  • @@class_variable@@开头,并与该类一起存储。他们是 在类的所有实例之间共享 - 以及子类的所有实例 那个班。
  • Constants以大写字母开头,可能全部上限。喜欢上课 变量,它们与当前self.class一起存储,但它们也是 细化层次结构 - 所以如果你在模块中定义了一个类, 类的实例也可以访问模块的常量。 在类之外定义的常量具有全局范围。 请注意,常量变量表示哪个对象绑定到常量 不会改变,也不会改变对象本身不会改变内部状态。
  • local_variables以小写字母开头

您可以阅读有关范围here的更多信息。

局部变量范围规则主要是标准规则 - 它们可用于 当我们进入时,except定义它们的所有子范围 模块,类或方法定义。因此,如果我们从您的代码中查看您的代码 答案

class TestDevice   
   attr_accessor :loghash
   def initialize  
    @loghash = { }  
   end  
end   

device = TestDevice.new

class Somethingelse
  def self.something
   device.loghash='something here' # doesn't work
  end
end

在顶层定义的device局部变量的范围不包括Somethingelse.something 方法定义。因此device方法定义中使用的Somethingelse.something局部变量是一个不同的(空)变量。如果希望范围界定以这种方式工作,则应使用常量或全局变量。

class TestDevice   
   attr_accessor :loghash
   def initialize  
    @loghash = { }  
   end  
end   

DEVICE = TestDevice.new
$has_logged = false

class Somethingelse
  def self.something
   DEVICE.loghash='something here'
   $has_logged = true
  end
end

p DEVICE.loghash  # prints `{}`
p $has_logged     # prints `false`
Somethingelse.something
p DEVICE.loghash  # prints `"something here"`
p $has_logged     # prints `true`