Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.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
Ruby 移除/取消定义类方法_Ruby_Metaprogramming - Fatal编程技术网

Ruby 移除/取消定义类方法

Ruby 移除/取消定义类方法,ruby,metaprogramming,Ruby,Metaprogramming,您可以为类动态定义类方法,如下所示: class Foo end bar = %q{def bar() "bar!" end} Foo.instance_eval(bar) 但是如何做相反的事情:删除/取消定义类方法?我怀疑模块的remove_方法和undef_方法可能可以用于此目的,但我在谷歌搜索数小时后看到的所有示例都是用于删除/取消定义实例方法,而不是类方法。或者,您也可以通过传递到instance\u eval来执行此操作 提前谢谢 class Foo def self.bar

您可以为类动态定义类方法,如下所示:

class Foo
end

bar = %q{def bar() "bar!" end}
Foo.instance_eval(bar)
但是如何做相反的事情:删除/取消定义类方法?我怀疑模块的
remove_方法
undef_方法
可能可以用于此目的,但我在谷歌搜索数小时后看到的所有示例都是用于删除/取消定义实例方法,而不是类方法。或者,您也可以通过传递到
instance\u eval
来执行此操作

提前谢谢

class Foo
  def self.bar
    puts "bar"
  end
end

Foo.bar    # => bar

class <<Foo
  undef_method :bar
end
# or
class Foo
  singleton_class.undef_method :bar
end

Foo.bar    # => undefined method `bar' for Foo:Class (NoMethodError)
有几种方法可以访问singleton类:

Foo -------------> Foo(singleton class) -------------> Object
        super      def bar             super
  • classObject.send(:remove\u const,:Foo)

    这也适用于我(不确定unde和remove\u方法之间是否有差异):


    我想我不能评论阿德里安的回答,因为我没有足够的可信度,但他的回答帮助了我


    我发现:
    undef
    似乎完全删除了该方法的存在,而
    remove\u method
    将其从该类中删除,但它仍将被定义在超类或扩展到该类的其他模块上,等等。

    如果您想删除名为dinamically的方法,您应该使用如下特征类:

    class Foo
      def self.bar
        puts "bar"
      end
    end
    
    name_of_method_to_remove = :bar
    eigenclass = class << Foo; self; end
    eigenclass.class_eval do
      remove_method name_of_method_to_remove
    end
    
    class-Foo
    def自我保护条
    “酒吧”
    结束
    结束
    要删除的方法的名称=:bar
    
    eigenclass=class您可以用两种简单的方法删除一个方法。激烈的

    Module#undef_method( ) 
    
    删除所有方法,包括继承的方法。善良者

    Module#remove_method( ) 
    
    从接收器中删除该方法,但 只保留继承的方法

    参见下面2个简单的例子-

    示例1使用undef_方法

    结果- $ruby main.rb


    “从一个类中得到x,我认为不使用本征类是可能的,至少在1.9中是这样。”安德鲁,也许是这样。唉,我不知道。这在Ruby1.9.3中对我不起作用。我仍然能够调用删除的方法。@joseph.hainline-这很有趣!我刚刚确认,上述方法在MRI 1.8.3-p374、MRI 1.9.3-p484、MRI 2.0.0-p247和MRI 2.1.0中有效。您是否正在执行一些不同的操作,无论是在删除该方法时,还是在调用该方法时,或者使用非MRI Ruby?@joseph.hainline-如果您在超类中有该方法,则在调用removed_方法后,该方法仍然可以调用。你可以使用undef_方法来阻止它。这不是删除整个类吗?从技术上来说,这个答案并不不准确(即,这实际上是删除类方法的一种方法),因为通过删除类Foo,它也会删除Foo:P:P中的所有类方法。我的意思是,这显然不是OP真正想要的,但从技术上讲,它不是错误的。其他技术上正确的答案:1)杀死包含Ruby的进程;2) 重启操作系统;3) 把电脑扔进湖里;4) 在附近投放核弹,;5) 触发超新星;6) 等着宇宙热死吧,这对我来说很有效。我在一个对象上调用它,它只在对象级别删除它。Foo.new.instance_eval{undef:color}也可以使用。removed_方法删除receiver类的方法,其中as undef_方法从继承类中删除了包括receiver类在内的所有方法。在Ruby 2.4中,它现在看起来是
    undef_方法
    Module#remove_method( ) 
    
    class A 
        def x
            puts "x from A class"
        end
    end
    
    class B < A
        def x
            puts "x from B Class"
        end
        undef_method :x
    end
    
    obj = B.new
    obj.x
    
    class A 
        def x
            puts "x from A class"
        end
    end
    
    class B < A
        def x
            puts "x from B Class"
        end
        remove_method :x
    end
    
    obj = B.new
    obj.x