我如何从Rational(或任何没有构造函数的类)继承?

时间:2022-06-02 22:39:35

I can easily inherit from, say, String for example, like this:

我可以很容易地继承,例如,String,例如:

class MyString < String
  def stuff
    self + ' and stuff'
  end
end

# This works:
MyString.new('things').stuff # => 'things and stuff'

But how can I inherit from Rational, which has no constructor? For example:

但是我如何从没有构造函数的Rational继承?例如:

def MyRat < Rational
  def inc
    self + 1
  end
end

# I have tried to initialize like this:
MyRat.new(10).inc # => NoMethodError: undefined method `new' for MyRat:Class
MyRat(10).inc # => NoMethodError: undefined method `MyRat' for main:Object
MyRat.send(:initialize, 10).inc  # => TypeError: already initialized class
# ???
# None of it works!

I can't find a way to initialize my new class.

我找不到初始化新课程的方法。

1 个解决方案

#1


5  

You can define your own object to be a proxy around Rational.

您可以将自己的对象定义为Rational的代理。

class MyRat < BasicObject
  def initialize(value)
    @rational = Rational(value)
  end

  def inc
    @rational + 1
  end

  def method_missing(name, *args, &block)
    @rational.send(name, *args, &block)
  end
end

Methods defined in your class will be used, otherwise the class will delegate to the rational instance.

将使用您的类中定义的方法,否则该类将委托给有理实例。

r = MyRat.new(10)

# MyRat#inc is used
r.inc
# => (11/1) 

# to_int delegates to Rational
r.to_int
# => 10 

A partial explanation of because Numeric has no initialize is available in this thread

由于Numeric没有初始化的部分解释在此线程中可用

Looking at the C code, I see that new() exists in Numeric and Float, but it is specifically removed: rb_cInteger = rb_define_class("Integer", rb_cNumeric); rb_undef_alloc_func(rb_cInteger); rb_undef_method(CLASS_OF(rb_cInteger), "new");

查看C代码,我看到new()存在于Numeric和Float中,但它被特别删除:rb_cInteger = rb_define_class(“Integer”,rb_cNumeric); rb_undef_alloc_func(rb_cInteger); rb_undef_method(CLASS_OF(rb_cInteger),“new”);

#....and for floats..
rb_undef_alloc_func(rb_cFloat);
rb_undef_method(CLASS_OF(rb_cFloat), "new");

The ruby source code contains no explanation for the removal of new. That's why I'm wondering what the reasoning behind this was. It does not seem to be technical limitation in the ruby interpreter. Currently, it does not make much sense to me.

ruby源代码不包含删除new的说明。这就是为什么我想知道这背后的原因是什么。它似乎不是ruby解释器中的技术限制。目前,这对我来说没有多大意义。

and the reason is because

原因是因为

It's an internal optimization. Fixnums do not have to be created and they never have to be GC'ed. This goes a long way to make math faster than it would be with ordinary objects (at least for Fixnums).

这是一个内部优化。不必创建Fixnums,它们永远不必是GC。这使得数学比普通对象更快(至少对于Fixnums而言)。

Additional suggestions and alternatives are explained in this article The Complete Numeric Class.

本文“完整数值类”中介绍了其他建议和替代方法。

#1


5  

You can define your own object to be a proxy around Rational.

您可以将自己的对象定义为Rational的代理。

class MyRat < BasicObject
  def initialize(value)
    @rational = Rational(value)
  end

  def inc
    @rational + 1
  end

  def method_missing(name, *args, &block)
    @rational.send(name, *args, &block)
  end
end

Methods defined in your class will be used, otherwise the class will delegate to the rational instance.

将使用您的类中定义的方法,否则该类将委托给有理实例。

r = MyRat.new(10)

# MyRat#inc is used
r.inc
# => (11/1) 

# to_int delegates to Rational
r.to_int
# => 10 

A partial explanation of because Numeric has no initialize is available in this thread

由于Numeric没有初始化的部分解释在此线程中可用

Looking at the C code, I see that new() exists in Numeric and Float, but it is specifically removed: rb_cInteger = rb_define_class("Integer", rb_cNumeric); rb_undef_alloc_func(rb_cInteger); rb_undef_method(CLASS_OF(rb_cInteger), "new");

查看C代码,我看到new()存在于Numeric和Float中,但它被特别删除:rb_cInteger = rb_define_class(“Integer”,rb_cNumeric); rb_undef_alloc_func(rb_cInteger); rb_undef_method(CLASS_OF(rb_cInteger),“new”);

#....and for floats..
rb_undef_alloc_func(rb_cFloat);
rb_undef_method(CLASS_OF(rb_cFloat), "new");

The ruby source code contains no explanation for the removal of new. That's why I'm wondering what the reasoning behind this was. It does not seem to be technical limitation in the ruby interpreter. Currently, it does not make much sense to me.

ruby源代码不包含删除new的说明。这就是为什么我想知道这背后的原因是什么。它似乎不是ruby解释器中的技术限制。目前,这对我来说没有多大意义。

and the reason is because

原因是因为

It's an internal optimization. Fixnums do not have to be created and they never have to be GC'ed. This goes a long way to make math faster than it would be with ordinary objects (at least for Fixnums).

这是一个内部优化。不必创建Fixnums,它们永远不必是GC。这使得数学比普通对象更快(至少对于Fixnums而言)。

Additional suggestions and alternatives are explained in this article The Complete Numeric Class.

本文“完整数值类”中介绍了其他建议和替代方法。