将初始化方法重命名为更友好的 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 检查一下...

https://rubygems.org/gems/new_init

无代码 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

如果不更改语言规范,这是不可能做到的。

但首先,我将向您展示是什么

#initializeClass#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 文化。