将初始化方法重命名为更友好的 init
Rename initialize method to the more friendly init
将ruby中的长'initialize'方法重命名为类似的最佳方法是什么Objective-C 'init',因此在任何 class 定义中我们可以只说
def init
end
而不是
def initialize
end
?
更新
我想创建一个 init 作为初始化并接受传递给 Object.new(*args, &block) 的参数和块 我需要一个名为 init 的典型初始化方法 .new 调用而不是初始化这样我就可以将参数和块通过它传递给原始参数。嗯,寻找与对象创建挂钩并初始化自身的东西。某种回电。
更新 2
我已经把正确答案变成了 gem 检查一下...
无代码 initialize
方法?什么都不做。
class Foo
# no meaningful initialize
end
到目前为止,最好的方法就是不这样做。额外的 6 个字符不会杀死您,而且非常值得拥有,以保持您的 ruby 惯用。然而,如果你真的想要,你可以用猴子补丁来完成:
# Monkey patch BasicObject (which your class will inherit from) such that
# it's initialize method just passes on params to init
class BasicObject
def initialize(*args)
init(*args) if respond_to? :init
end
end
class MyClass
def init(test1, test2)
puts "Params are: #{test1}, #{test2}"
end
def say_hello
puts "Hello from a class that uses init rather than initialize"
end
end
x = MyClass.new('Hello', 'World')
x.say_hello
重申一下,这是个坏主意。别这样。
class Object
#alias_method :native_initialize, :initialize
def initialize
#native_initialize
init if respond_to? :init
end
end
class Duck
def init
p "QUA QUA"
end
end
Duck.new
如果不更改语言规范,这是不可能做到的。
但首先,我将向您展示是什么。
#initialize
被 Class#new
调用。 Class#new
基本上是这样的:
class Class
def new(*args, &block)
obj = allocate
obj.initialize(*args, &block)
obj
end
end
除了 initialize
默认为 private
,所以您 实际上 需要这样做:
class Class
def new(*args, &block)
obj = allocate
obj.__send__(:initialize, *args, &block)
obj
end
end
现在,很明显您需要做什么来更改方法的名称:只需 monkeypatch Class#new
来调用 init
而不是 initialize
:
class Class
def new(*args, &block)
obj = allocate
obj.init(*args, &block)
obj
end
end
轰!大功告成。
但是,这是不的等价物!注意我上面是怎么说 initialize
默认是 private
的?那是"magic"!名称initialize
的特殊之处在于,与其他默认为public
的方法不同,名为initialize
的方法默认为private
:
class Foo
def initialize; end
def init; end
end
Foo.private_instance_methods(false)
#=> [:initialize]
Foo.public_instance_methods(false)
#=> [:init]
这是 Ruby 语言规范的一部分,无法在 Ruby 中表达。
另请注意,既然您已通过 monkeypatched Class#new
调用 init
而不是 initialize
,您需要重命名系统中每个现有的 initialize
方法,否则,他们不会被调用!
ObjectSpace.each_object(Module).
select {|m| m.instance_methods(false).include?(:initialize) }.
each do |m|
m.alias_method :init, :initialize
end
class Class
def new(*args, &block)
obj = allocate
obj.init(*args, &block)
obj
end
end
ObjectSpace.each_object(Module).
select {|m| m.instance_methods(false).include?(:initialize) }.
each do |m|
m.remove_method :initialize
end
此代码几乎肯定会使任何现实世界的程序崩溃,因为对名称 initialize
的依赖太深地融入了现有的 Ruby 代码和 Ruby 文化。
将ruby中的长'initialize'方法重命名为类似的最佳方法是什么Objective-C 'init',因此在任何 class 定义中我们可以只说
def init
end
而不是
def initialize
end
?
更新
我想创建一个 init 作为初始化并接受传递给 Object.new(*args, &block) 的参数和块 我需要一个名为 init 的典型初始化方法 .new 调用而不是初始化这样我就可以将参数和块通过它传递给原始参数。嗯,寻找与对象创建挂钩并初始化自身的东西。某种回电。
更新 2
我已经把正确答案变成了 gem 检查一下...
无代码 initialize
方法?什么都不做。
class Foo
# no meaningful initialize
end
到目前为止,最好的方法就是不这样做。额外的 6 个字符不会杀死您,而且非常值得拥有,以保持您的 ruby 惯用。然而,如果你真的想要,你可以用猴子补丁来完成:
# Monkey patch BasicObject (which your class will inherit from) such that
# it's initialize method just passes on params to init
class BasicObject
def initialize(*args)
init(*args) if respond_to? :init
end
end
class MyClass
def init(test1, test2)
puts "Params are: #{test1}, #{test2}"
end
def say_hello
puts "Hello from a class that uses init rather than initialize"
end
end
x = MyClass.new('Hello', 'World')
x.say_hello
重申一下,这是个坏主意。别这样。
class Object
#alias_method :native_initialize, :initialize
def initialize
#native_initialize
init if respond_to? :init
end
end
class Duck
def init
p "QUA QUA"
end
end
Duck.new
如果不更改语言规范,这是不可能做到的。
但首先,我将向您展示是什么。
#initialize
被 Class#new
调用。 Class#new
基本上是这样的:
class Class
def new(*args, &block)
obj = allocate
obj.initialize(*args, &block)
obj
end
end
除了 initialize
默认为 private
,所以您 实际上 需要这样做:
class Class
def new(*args, &block)
obj = allocate
obj.__send__(:initialize, *args, &block)
obj
end
end
现在,很明显您需要做什么来更改方法的名称:只需 monkeypatch Class#new
来调用 init
而不是 initialize
:
class Class
def new(*args, &block)
obj = allocate
obj.init(*args, &block)
obj
end
end
轰!大功告成。
但是,这是不的等价物!注意我上面是怎么说 initialize
默认是 private
的?那是"magic"!名称initialize
的特殊之处在于,与其他默认为public
的方法不同,名为initialize
的方法默认为private
:
class Foo
def initialize; end
def init; end
end
Foo.private_instance_methods(false)
#=> [:initialize]
Foo.public_instance_methods(false)
#=> [:init]
这是 Ruby 语言规范的一部分,无法在 Ruby 中表达。
另请注意,既然您已通过 monkeypatched Class#new
调用 init
而不是 initialize
,您需要重命名系统中每个现有的 initialize
方法,否则,他们不会被调用!
ObjectSpace.each_object(Module).
select {|m| m.instance_methods(false).include?(:initialize) }.
each do |m|
m.alias_method :init, :initialize
end
class Class
def new(*args, &block)
obj = allocate
obj.init(*args, &block)
obj
end
end
ObjectSpace.each_object(Module).
select {|m| m.instance_methods(false).include?(:initialize) }.
each do |m|
m.remove_method :initialize
end
此代码几乎肯定会使任何现实世界的程序崩溃,因为对名称 initialize
的依赖太深地融入了现有的 Ruby 代码和 Ruby 文化。