gpt4 book ai didi

ruby-on-rails - 如何判断类中是否定义了一个方法?

转载 作者:数据小太阳 更新时间:2023-10-29 06:52:00 25 4
gpt4 key购买 nike

class C1
unless method_defined? :hello # Certainly, it's not correct. I am asking to find something to do this work.
def_method(:hello) do
puts 'Hi Everyone'
end
end
end

那么,如何判断一个方法是否定义了呢?

最佳答案

您发布的代码可以很好地检查方法是否已定义。 Module#method_defined?正是正确的选择。 (还有变体 Module#public_method_defined?Module#protected_method_defined?Module#private_method_defined? 。)问题在于您对 def_method 的调用,它不存在。 (称为 Module#define_method )。

这就像一个魅力:

class C1      
define_method(:hello) do
puts 'Hi Everyone'
end unless method_defined? :hello
end

但是,因为你已经提前知道了名称并且没有使用任何闭包,所以没有必要使用Module#define_method,你可以直接使用def 改为关键字:

class C1
def hello
puts 'Hi Everyone'
end unless method_defined? :hello
end

或者我误解了你的问题,你担心继承?在这种情况下,Module#method_defined? 不是正确的选择,因为它遍历了整个继承链。在这种情况下,您将不得不使用 Module#instance_methods或其堂兄弟之一Module#public_instance_methods , Module#protected_instance_methodsModule#private_instance_methods ,它带有一个可选参数,告诉他们是否包含来自父类(super class)/mixin 的方法。 (请注意文档是错误的:如果您不传递任何参数,它包含所有继承的方法。)

class C1
unless instance_methods(false).include? :hello
def hello
puts 'Hi Everyone'
end
end
end

这是一个小测试套件,表明我的建议有效:

require 'test/unit'
class TestDefineMethodConditionally < Test::Unit::TestCase
def setup
@c1 = Class.new do
def self.add_hello(who)
define_method(:hello) do
who
end unless method_defined? :hello
end
end

@o = @c1.new
end

def test_that_the_method_doesnt_exist_when_it_hasnt_been_defined_yet
assert !@c1.method_defined?(:hello)
assert !@c1.instance_methods.include?(:hello)
assert !@o.methods.include?(:hello)
assert !@o.respond_to?(:hello)
assert_raise(NoMethodError) { @o.hello }
end

def test_that_the_method_does_exist_after_it_has_been_defined
@c1.add_hello 'one'

assert @c1.method_defined?(:hello)
assert @c1.instance_methods.include?(:hello)
assert @o.methods.include?(:hello)
assert_respond_to @o, :hello
assert_nothing_raised { @o.hello }
assert_equal 'one', @o.hello
end

def test_that_the_method_cannot_be_redefined
@c1.add_hello 'one'

assert @c1.method_defined?(:hello)
assert @c1.instance_methods.include?(:hello)
assert @o.methods.include?(:hello)
assert_respond_to @o, :hello
assert_nothing_raised { @o.hello }
assert_equal 'one', @o.hello

@c1.add_hello 'two'

assert @c1.method_defined?(:hello)
assert @c1.instance_methods.include?(:hello)
assert @o.methods.include?(:hello)
assert_respond_to @o, :hello
assert_nothing_raised { @o.hello }
assert_equal 'one', @o.hello, 'it should *still* respond with "one"!'
end
end

关于ruby-on-rails - 如何判断类中是否定义了一个方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3403004/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com