0

我对Ruby真的很陌生。和新的 - 不到 16 小时,但我的老板给了我一些 Ruby 代码来添加。但是,我发现它是一个巨大的文件,根本不是模块化的,所以我决定清理它。现在我已经将它分解为几个文件/类(一般来说,每个文件 1 个类),我在将它拼凑在一起以使其再次工作时遇到了问题。最初一切都是同一个班级的一部分,所以电话工作,但它看起来很丑,花了一整天的时间才弄明白。我想在未来避免这种情况,因为这段代码在完成之前会变得更大。

我的主要问题如下所示(显然是简化的):

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”的内容传递给每个方法之外实现这一点,以便他们反过来可以传递它,然后将值返回到起始点,然后记录它最后,但这似乎真的很笨拙和尴尬。

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

4

3 回答 3

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在幕后所做的。

于 2009-02-28T08:44:27.997 回答
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  
于 2009-02-28T10:38:21.470 回答
2

所以你需要学习 ruby​​ 作用域的规则。

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

  • $global_variables以 ,开头,$每个人都可以使用。
  • @instance_variables以单个 开头@,并与 的当前值一起存储self。如果两个作用域共享相同的值self(例如,它们都是实例方法),那么它们都共享相同的实例变量
  • @@class_variable以 ,开头@@,并与类一起存储。它们在一个类的所有实例以及该类的所有子类实例之间共享。
  • Constants以大写字母开头,并且可能全部大写。像类变量一样,它们与 current 一起存储self.class,但它们也会在层次结构中涓涓细流——因此,如果您在模块中定义了一个类,则该类的实例也可以访问该模块的常量。在类之外定义的常量具有全局范围。请注意,常量变量意味着绑定到常量的对象不会改变,而不是对象本身不会改变内部状态。
  • local_variables以小写字母开头

您可以在此处阅读有关范围的更多信息。

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`
于 2009-03-01T16:40:40.153 回答