Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何调用类';s方法,当调用该类的任何其他方法时(Ruby)_Ruby_Class - Fatal编程技术网

如何调用类';s方法,当调用该类的任何其他方法时(Ruby)

如何调用类';s方法,当调用该类的任何其他方法时(Ruby),ruby,class,Ruby,Class,在Ruby中,当类的任何其他方法被调用时,有没有一种方法可以调用该方法? 比如说, class Car def repair puts "Repaired!" end def drive # content end def checkup # content end end 在本例中,如果我对Car的实例调用任何方法,我应该始终调用repair方法。我如何在Ruby中实现这一点 注意:我也希望rep

在Ruby中,当类的任何其他方法被调用时,有没有一种方法可以调用该方法? 比如说,

class Car
    def repair
        puts "Repaired!"
    end
    def drive
        # content
    end
    def checkup
        # content
    end
end
在本例中,如果我对
Car
的实例调用任何方法,我应该始终调用
repair
方法。我如何在Ruby中实现这一点


注意:我也希望
repair
调用内置方法,比如
Carinstance。类
也应该调用
repair

我假设您希望
Car#repair
在每个
Car
的其他实例方法返回后调用。我看到您添加了一个要求,其他方法也会调用
repair
。我在最后补充了一些关于扩展它以包括内置实例方法的意见

我采取的方法是利用:

当解析class
Car
时,在构造完所有实例方法之后,将执行以下操作,我将用一个示例来解释:

instance_methods(false) # => [:repair, :drive, :checkup, :method_missing]  
每个带有对象({})的\u创建一个散列(最初为空),由块变量
h
引用(稍后将对此进行详细介绍)

导致跳过
:修复
:方法_缺失

m=>:drive
时,以下三条语句有效地将
:drive
重命名为
:\u drive
,并将
:drive“=>”\u drive“
添加到散列
h

每个带有\u对象的\u
返回

@@ims = {:drive=>"_drive", :checkup=>"_checkup"}
现在呢

instance_methods(false) # => [:repair, :method_missing, :_drive, :_checkup]
因为不再有方法
:drive
Car.new.drive
调用
方法\u missing(:drive)
。后者发现
@@ims
有一个键
:drive
,因此它使用
send
来调用
:\u drive
,调用
:repair
并返回
:\u drive
的返回值。如果
方法\u missing
传递了一个不是
@@ims
键的方法,则调用
super
并引发异常

在现在删除的编辑中,我建议要包含内置实例方法,只需更改
instance_方法(false)
实例\u方法
,但警告可能会产生意外的副作用。@Kal指出,内置实例方法无法删除,因此这种方法不会起作用。这也很好——人们不应该以这种方式干扰Ruby。我显然没有测试我的断言。真丢脸

class Car
  def self.default_method
      instance_methods(true).each do |meth|
        alias_method meth, :repair
      end
  end
  def initialize
    self.class.default_method
  end

  def repair
    puts "Repaired!"
  end
  def drive
    # content
  end
  def checkup
    # content
  end
end

car = Car.new

car.drive # => Repaired!
car.checkup # => Repaired!
car.class # => Repaired!
请注意,重新定义内置方法会产生一些警告:

# => untitled 5:6: warning: redefining `object_id' may cause serious problems
# => untitled 5:6: warning: redefining `__send__' may cause serious problems

Edit:Oops,我发布这个太快了,没有发现问题。它调用了
repair
,但不是原始的方法。我知道这看起来太简单了!我想我对这个问题有点不知所措。:-)(注意:我认为Cary的方法真的很聪明,它确实适用于您自己的方法,但看起来他使用内置方法走到了死胡同,而且在任何情况下,它以一种您不应该尝试使用内置方法的方式改变了方法).

除了在每个方法中调用
repair
之外?是的。对于.class之类的内置方法",它应该在那里调用
repair
,to.
Car
类只是我需要的一个例子。为什么要将它用于内置方法?如果不想从内置方法调用它,可以在initialize中调用repair。内置方法可能需要元编程魔法。@Kal-Duh!你是对的。这是面向方面的程序mming.In Ruby根据这篇博客文章使用alias_方法实现!你能将它修改为使用
实例_方法(true)
这样它也包括内置方法吗?看起来remove_方法(m)不适用于内置(继承的)方法。我得到错误“NameError:方法‘nil’?”没有在Car中定义.也许是时候向OP建议,在
对象
类中乱搞方法不是个好主意,或者有解决办法吗?卡尔,这很有道理。我不测试的时候似乎总是会被烧焦。我会编辑我的答案。谢谢。晚了一点,但谢谢你!效果很好。嘿@Kal,我喜欢你的答案,我试过了,我喜欢除了一个问题外,t工作得很好:我希望在原始方法内容之外调用
repair
。例如:
car.methods
应该调用
repair
,但仍然应该返回一个方法数组,
car.class
除了返回类之外,还应该调用
repair
。感谢您的帮助!是的,对不起,我提到我的答案在底部的编辑中无法正常工作。我发布得太快了,一开始没有注意到,因为驱动器和检查方法没有输出任何内容。我还应该删除注释“但它可以工作!”,我现在就这么做。:-)
instance_methods(false) # => [:repair, :method_missing, :_drive, :_checkup]
class Car
  def self.default_method
      instance_methods(true).each do |meth|
        alias_method meth, :repair
      end
  end
  def initialize
    self.class.default_method
  end

  def repair
    puts "Repaired!"
  end
  def drive
    # content
  end
  def checkup
    # content
  end
end

car = Car.new

car.drive # => Repaired!
car.checkup # => Repaired!
car.class # => Repaired!
# => untitled 5:6: warning: redefining `object_id' may cause serious problems
# => untitled 5:6: warning: redefining `__send__' may cause serious problems