提问人:Nnamdi 提问时间:8/26/2022 最后编辑:Nnamdi 更新时间:8/27/2022 访问量:64
Ruby 常量在另一个类中调用时返回 nil
Ruby constant returning nil when called in another class
问:
我有这个班级
class Foo
MAIN_COMPUTER = @computer_name
attr_accessor :computer_name
def initialize
@computer_name = "IComputer"
end
end
当我尝试在另一个类的方法中访问 MAIN_COMPUTER 变量时,即使 Foo 类的对象已被初始化,它也会返回 nil
class Gamer
def opponent
Foo::MAIN_COMPUTER
end
end
me = Gamer.new
me.opponent 返回 nil。有没有办法让 Foo::MAIN_COMPUTER 从对手方法定义中引用“IComputer”?有没有其他方法可以实现这一目标?
任何帮助将不胜感激。先谢谢你!
编辑 1
class Foo
attr_accessor :computer_name
def initialize
@computer_name = "IComputer"
end
def self.main_computer
@computer_name
end
end
class Gamer
def opponent
Foo.main_computer
end
end
me = Gamer.new
p me.opponent
代码的最后一行返回 nil。请您解释一下吗?谢谢
答:
1赞
Stefan
8/27/2022
#1
从您的评论来看,您似乎希望拥有单个实例和一些可以全局引用的“主”实例。Foo
Foo
常量不应该改变(因此得名),所以如果你想让“main”对象是可改变的,你可能应该改用类方法。
要向类本身添加属性,请执行以下操作:
class Foo
class << self
attr_accessor :main_computer
end
attr_accessor :computer_name
def initialize(computer_name)
@computer_name = computer_name
end
end
调用 within 将创建两个方法:一个 getter 和一个 setter 。该值将存储在名为的类实例变量中(即直接在类内部,而不是其实例中)。attr_accessor :main_computer
class << self
Foo.main_computer
Foo.main_computer=
@main_computer
初始值为:nil
Foo.main_computer
#=> nil
您现在可以创建一个新实例,然后将其分配给:Foo
main_computer
foo = Foo.new("HAL 9000")
#=> #<Foo:0x00007f81321827d8 @computer_name="HAL 9000">
Foo.main_computer = foo
这将允许您从另一个类引用该实例:
Foo.main_computer
#=> #<Foo:0x00007f81321827d8 @computer_name="HAL 9000">
或者,要获得它的名字:
Foo.main_computer.computer_name
#=> "HAL 9000"
您还可以将初始值设定项分配给:Foo
main_computer
def initialize(computer_name)
@computer_name = computer_name
Foo.main_computer = self
end
若要仅在已存在 no 时进行分配,请使用条件分配:main_computer
def initialize(computer_name)
@computer_name = computer_name
Foo.main_computer ||= self
end
评论
Foo::MAIN_COMPUTER
总是在这里,不管你从哪里称呼它。那是因为只会将 from (此时) 的值分配给常量。它不会将常量“链接”到变量。此外,前者是类实例变量,而后者(内部)是“正常”实例变量。nil
MAIN_COMPUTER = @computer_name
@computer_name
nil
@computer_name
initialize
Foo
compurer_name
MAIN_COMPUTER