如何从Rational(或任何没有构造函数的类)继承? [英] How can I inherit from Rational (or any class with no constructor)?

查看:124
本文介绍了如何从Rational(或任何没有构造函数的类)继承?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

例如,我可以轻松地从String继承,

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

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

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

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

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

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.

推荐答案

您可以将自己的对象定义为Rational周围的代理.

You can define your own object to be a proxy around 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 

此线程中提供了关于因为Numeric没有初始化的部分解释

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

看一下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");

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");

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

ruby​​源代码未包含有关删除新内容的说明. 这就是为什么我想知道这背后的原因是什么.确实 在ruby解释器中似乎不是技术限制. 目前,这对我来说意义不大.

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.

原因是因为

这是内部优化. Fixnums不必创建, 他们永远不必被GC.这大大加快了数学的速度 比普通对象要多(至少对于Fixnums).

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).

本文完整的数字类 查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆