如果ruby`Complex`是一个类,它怎么能像方法一样被调用?

时间:2015-03-07 08:26:41

标签: ruby

Ruby核心库可以调用Complex类,就好像它是方法一样。

Complex.class #=> Class
Complex(1, 2) #=> (1+2i)

这怎么可能?

我可以覆盖[],但不能覆盖()

class MyComplex
  def self.[](real, image) # This works.
    "#{real} + #{image}i"
  end
  def self.()(real, image) # This is not allowed in ruby.
    "#{real} + #{image}i"
  end
end

MyComplex[1,2] #=> "1+2i"
MyComplex(1,2) # I want this working like Complex class.

3 个答案:

答案 0 :(得分:3)

你的假设是错误的。 Complex中的Complex.class是一个类,Complex中的Complex(1, 2)Kernel上定义的方法。它们是不同的东西。

答案 1 :(得分:2)

那么你需要将初始化放在Kernel模块中。

module Kernel
  def MyComplex
   MyComplex.new
  end
end

Ruby核心库在Kernel模型中定义了#Complex()。如果您在Kernel模块中定义它,那么您可以使用 mixin 来利用这些方法,如下所示:

class MyComplex
  def initialize( real, image )
    "#{real} + #{image}i"
  end
end

module Kernel
  def MyComplex( real, image )
    MyComplex.new real, image
  end
end

class Klass < BasicObject
  include ::Kernel

  def create_object a, b
    MyComplex(a, b)
  end
end

p Klass.new.create_object 1, 2
# >> #<MyComplex:0xa01b008>

如果您在顶级中定义它,该方法将成为类Object私有方法,那么您没有简单的方法来重用该方法:

def MyComplex( real, image )
  MyComplex.new real, image
end

class Klass < BasicObject
  def create_object a, b
    MyComplex(a, b)
  end
end

p Klass.new.create_object 1, 2
# `create_object': undefined method `MyComplex'

答案 2 :(得分:2)

实际上非常简单,而AFAIK就是Ruby和Ruby库的用法:

class MyComplex
  def self.[](real, image) # This works.
    "#{real} + #{image}i"
  end
end

def MyComplex( real, image )
  "#{real} + #{image}i"
end

MyComplex[1,2] # "1+2i"
MyComplex(1,2) # "1+2i"