Ruby “为什么?”;发送(:initialize,*args,**kwargs,&;block)";仅在类内失败#新?
我已经在这上面呆了很长时间了。看看这个:Ruby “为什么?”;发送(:initialize,*args,**kwargs,&;block)";仅在类内失败#新?,ruby,ruby-2.2,Ruby,Ruby 2.2,我已经在这上面呆了很长时间了。看看这个: class SuperClass def self.new(*args, **kwargs, &block) i = allocate() # Extra instance setup code here i.send(:initialize, *args, **kwargs, &block) return i end end class Test < SuperClass def
class SuperClass
def self.new(*args, **kwargs, &block)
i = allocate()
# Extra instance setup code here
i.send(:initialize, *args, **kwargs, &block)
return i
end
end
class Test < SuperClass
def initialize
puts "No args here"
end
end
然而,这并不是:
t = Test.new
但显然,它只有在new
方法中调用时才会失败。我已经确认了args=[]
,kwargs=={}
和block==nil
有人能解释这一点吗
Ruby版本: ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-linux] ruby 2.2.3p173(2015-08-18修订版51636)[x86_64-linux]
请不要建议我不要超载
类。新建。我知道我可以使用Class.inherited
和Class.append
获得相同的结果。这个问题只是关于调用initialize
失败的原因。一个简单的*args
将捕获包括关键字参数在内的所有参数,以防您不需要在new
方法中单独引用kwargs
:
class SuperClass
def self.new(*args, &block)
i = allocate
# Extra instance setup code here
i.send(:initialize, *args, &block)
i
end
end
一个简单的*args
将捕获包括关键字参数在内的所有参数,以防您不需要在new
方法中单独引用kwargs
:
class SuperClass
def self.new(*args, &block)
i = allocate
# Extra instance setup code here
i.send(:initialize, *args, &block)
i
end
end
让我们看一个更简单的例子,特别是因为问题没有问题那么具体,问题的标题让问题看起来像,但你自己看
def m # takes no arguments
end
m(**{}) # no argument is passed
h = {}
m(**h) # an argument is passed => ArgumentError is raised
这种不一致性是在2.2.1中由一个旨在修复涉及**{}
()的分段错误的提交引入的。提交特殊情况**{}
以不传递参数。其他方式,如**Hash.new
和h={}**h
仍将空哈希作为参数传递
以前的版本始终会引发ArgumentError
()。我可能错了,但我相信这是我的本意。然而,它可能是也可能不是真正想要的。因此,如果您认为双重散列空散列不应该传递参数(比如现在的**{}
),因此其工作原理类似于散列空数组,那么关于这一点,有一个公开的问题()。它还提到了这种相对较新的不一致性。让我们看一个更简单的例子,特别是因为问题没有问题那么具体,问题的标题让它看起来像,但你自己看
def m # takes no arguments
end
m(**{}) # no argument is passed
h = {}
m(**h) # an argument is passed => ArgumentError is raised
这种不一致性是在2.2.1中由一个旨在修复涉及**{}
()的分段错误的提交引入的。提交特殊情况**{}
以不传递参数。其他方式,如**Hash.new
和h={}**h
仍将空哈希作为参数传递
以前的版本始终会引发ArgumentError
()。我可能错了,但我相信这是我的本意。然而,它可能是也可能不是真正想要的。因此,如果您认为双重散列空散列不应该传递参数(比如现在的**{}
),因此其工作原理类似于散列空数组,那么关于这一点,有一个公开的问题()。它还提到了这种相对较新的不一致性。它似乎与i.send(:initialize,*args,**kwargs,&block)一起工作。
更改为i.send(:initialize,*args,&block)
@CarySwoveland。就我所见,它的行为似乎是相同的。原因似乎是**kwargs
将零个或多个关键字参数转换为散列,因此如果没有,则会得到一个空散列,这当然是一个参数。您可以很容易地测试它。@CarySwoveland但是send(:initialize,*[],***{},&nil)
在其他地方工作,没有参数被发送到initialize
。这个问题只发生在类#new
方法中。我们发现错误了吗?@cremno So 2.2.0仍然具有正确的行为,而更高版本由于延迟的segfault修复而具有错误的行为:PIt似乎与i.send(:initialize,*args,**kwargs,&block)一起工作。
更改为i.send(:initialize,*args,&block)
@CarySwoveland。就我所见,它的行为似乎是相同的。原因似乎是**kwargs
将零个或多个关键字参数转换为散列,因此如果没有,则会得到一个空散列,这当然是一个参数。您可以很容易地测试它。@CarySwoveland但是send(:initialize,*[],***{},&nil)
在其他地方工作,没有参数被发送到initialize
。这个问题只发生在类#new
方法中。我们发现错误了吗?@cremno So 2.2.0仍然具有正确的行为,而更高版本由于延迟的segfault修复而具有错误的行为:PI不知道新的,因为实例方法是一件事。。。现在我真的很困惑所有这些方法是如何结合在一起的。为什么它既可以是类方法又可以是实例方法呢?我想类方法内部只是为了方便起见调用实例方法new
,因此您可以正确地访问initialize
。红宝石魔术;-)尽管如此,我如何从已经分配的实例中分配一个新实例,并返回该实例?这对我来说仍然没有意义,我只是在Ruby 2.2.3中测试了这一点,而且从未调用过类#new
:SIt对我来说也没有意义,我必须为给你指出错误的方向而道歉。这篇博文是错误的,实际上你需要重写初始化
并使用发送
。不过,我回答的第二部分仍然有效。编辑…我不知道new
,因为实例方法是一件事。。。现在我真的很困惑所有这些方法是如何结合在一起的。为什么它既可以是类方法又可以是实例方法呢?我想类方法内部只是为了方便起见调用实例方法new
,因此您可以正确地访问initialize
。红宝石魔术;-)尽管如此,我如何从已经分配的实例中分配一个新实例,并返回该实例?这对我来说仍然没有意义,我只是在Ruby 2.2.3中测试了这一点,而Class#new
是n
def m # takes no arguments
end
m(**{}) # no argument is passed
h = {}
m(**h) # an argument is passed => ArgumentError is raised