如何为Ruby中的所有实例设置默认(而不是nil)变量初始化
实例变量在哪里第一次初始化为nil? 对于所有实例,我是否可以默认将其重新定义为其他值 例如:如何为Ruby中的所有实例设置默认(而不是nil)变量初始化,ruby,metaprogramming,Ruby,Metaprogramming,实例变量在哪里第一次初始化为nil? 对于所有实例,我是否可以默认将其重新定义为其他值 例如: class Class #some code here or maybe in an Object class end class Foo1 attr_accessor :bar end class Foo2 attr_accessor :bar end p Foo1.new.bar # result is not nil p Foo2.new.bar # result is not
class Class
#some code here or maybe in an Object class
end
class Foo1
attr_accessor :bar
end
class Foo2
attr_accessor :bar
end
p Foo1.new.bar # result is not nil
p Foo2.new.bar # result is not nil
class Test
attr_accessor :bar
def initialize
@bar = 'bar'
end
end
Test.new.bar
# => "bar"
这可以通过修改读卡器来完成:
class Class
def attr_accessor(attr_name)
...
define_method "#{attr_name}" do
if instance_variable_get "@#{attr_name}_history"
instance_variable_get "@#{attr_name}_history"
else
"Not nil"
end
end
...
end
end
但这无助于理解Ruby的核心。
非常感谢 (根据Jörg W Mittag的评论更正)
不,你不能。当您调用实例变量而不给它们赋值时,实例变量的求值设置为nil
。(根据Jörg W Mittag的评论更正)
不,你不能。当您调用实例变量而不给它们赋值时,实例变量的计算值被设置为
nil
。如果您想设置默认值,可以在类的初始化
方法中赋值
例如:
class Class
#some code here or maybe in an Object class
end
class Foo1
attr_accessor :bar
end
class Foo2
attr_accessor :bar
end
p Foo1.new.bar # result is not nil
p Foo2.new.bar # result is not nil
class Test
attr_accessor :bar
def initialize
@bar = 'bar'
end
end
Test.new.bar
# => "bar"
请记住,attr\u accessor:bar
为您提供了帮助器方法来设置和获取底层实例变量@bar
如果您想要许多类的默认值,可以让它们从将实例变量设置为not nil的类继承:
class Foo < Test
end
Foo.new.bar
# => "bar"
class Foo“巴”
如果要设置默认值,可以在类的initialize
方法中分配它们
例如:
class Class
#some code here or maybe in an Object class
end
class Foo1
attr_accessor :bar
end
class Foo2
attr_accessor :bar
end
p Foo1.new.bar # result is not nil
p Foo2.new.bar # result is not nil
class Test
attr_accessor :bar
def initialize
@bar = 'bar'
end
end
Test.new.bar
# => "bar"
请记住,attr\u accessor:bar
为您提供了帮助器方法来设置和获取底层实例变量@bar
如果您想要许多类的默认值,可以让它们从将实例变量设置为not nil的类继承:
class Foo < Test
end
Foo.new.bar
# => "bar"
class Foo“巴”
在classclass
中定义一个新方法。通过:instance\u variables
获取实例变量,并使用:instance\u variable\u set(:@var,默认值)
在class
class
中定义新方法。通过:instance\u variables
获取实例变量,并使用:instance\u variable\u set(:@var,默认值)
变量未设置为任何值。它是未初始化的。未初始化变量的计算结果为
nil
。好的,第一位是什么,我不能初始化变量吗?是初始化方法吗?或者以前的某个地方?也许我可以重新定义某个类方法(新)?您可以定义initialize
,以便它为实例变量赋值。是的,但这只会更改一个类实例的行为。现在有办法在类或对象类中更改此设置吗?变量没有设置为任何值。它是未初始化的。未初始化变量的计算结果为nil
。好的,第一位是什么,我不能初始化变量吗?是初始化方法吗?或者以前的某个地方?也许我可以重新定义某个类方法(新)?您可以定义initialize
,以便它为实例变量赋值。是的,但这只会更改一个类实例的行为。现在有办法在类或对象类中改变这一点吗?这确实可以满足OP的要求(这是一个巧妙的技巧),但这可能会破坏ruby标准库和其他gems中的许多其他东西。是的,我同意。让我们补充一点警告:仅出于学术和学习目的,副作用包括破坏很多东西。但是我们可以将我们的方法命名为“default\u new”而不是“new”。因此使用'foo=foo.default\u new'很好!非常感谢,这就是我需要的!这确实可以满足OP的要求(这是一个巧妙的技巧),但这可能会破坏ruby标准库和其他gems中的许多其他东西。是的,我同意。让我们补充一点警告:仅出于学术和学习目的,副作用包括破坏很多东西。但是我们可以将我们的方法命名为“default\u new”而不是“new”。因此使用'foo=foo.default\u new'很好!非常感谢,这就是我需要的!我想对任何可能在这个问题上绊倒的新ruby程序员发出一个明确的警告:要小心。如果您想改变这种核心ruby功能的行为,我建议您重新考虑。它会导致其他人难以维护的编程习惯和代码。当一段代码的功能增加时,更改所有类的所有属性的默认值似乎不具有很强的可伸缩性。根据您尝试执行的操作,可能有更好的替代方法。你可以问社区关于如何处理你的案件的建议(通过问你自己的问题)。确保提供足够的上下文来解释为什么您认为覆盖这样的核心方法是您唯一的选择。从长远来看,您可能会学习提高逻辑和编码技能。我想向任何可能在这个问题上遇到困难的新ruby程序员发出一个明确的警告:要小心。如果您想改变这种核心ruby功能的行为,我建议您重新考虑。它会导致其他人难以维护的编程习惯和代码。当一段代码的功能增加时,更改所有类的所有属性的默认值似乎不具有很强的可伸缩性。根据您尝试执行的操作,可能有更好的替代方法。你可以问社区关于如何处理你的案件的建议(通过问你自己的问题)。确保提供足够的上下文来解释为什么您认为覆盖这样的核心方法是您唯一的选择。从长远来看,您可能会学习提高逻辑和编码技能。