我是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”的内容传递给每个方法之外发生这种情况,以便它们反过来可以传递它,然后将值返回到原始点然后记录它最后,但这看起来非常笨拙和尴尬。
我希望我真的只是错过了一些东西。
答案 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`