如何检查模块是否响应类方法?

时间:2017-10-27 23:11:33

标签: ruby

使用Ruby, Rails。

我的Ruby应用程序提供了通过加载用户定义的模块来扩展其功能的能力。为简单起见,下面是有效模块的结构:

module MyModule
  class MyClass < AppSuperClass
    def initialize
      puts "Hello"
    end
  end

  def self.create_class
    return MyClass.new
  end
end

如您所见,该模块必须实现一个继承自AppSuperClass的类,并且必须实现一个名为create_class的模块方法。

如果上述模块位于文件mymodule.rb中,我将其包含在另一个文件中,如下所示:

require 'mymodule'

我需要检查MyModule是否响应MyModule.create_class。出于某种原因,MyModule.method_defined?(create_class)MyModule.method_defined(:create_class)都返回false。我做错了什么?

2 个答案:

答案 0 :(得分:1)

首先,您错过了end阻止def initialize,因此您的create_class方法已在MyClass正文中定义 - 您应该修复使这些错误更加明显的缩进。

修复此问题后,您可以使用MyModule.respond_to?(:create_class)method_defined?解释了num = int(input("Enter length:")) d = {"aet":['ate', 'eat', 'eta'], 'pol':['lop', 'pol']} vals = [i for i in d.values() if len(i) >= num] 无法按预期使用类方法工作的原因{。{3}}。

答案 1 :(得分:1)

发布后,您的代码无效:

$ ruby -w m.rb 
m.rb:5: warning: mismatched indentations at 'end' with 'def' at 3
m.rb:10: warning: mismatched indentations at 'end' with 'class' at 2
m.rb:10: syntax error, unexpected end-of-input, expecting keyword_end

$ ruby -w t.rb 
t.rb:3:in `<main>': undefined local variable or method `create_class' for main:Object (NameError)

更改MyModule.method_defined?(create_class)

MyModule.method_defined?(:create_class)

$ ruby -w t.rb 
false
t.rb:4:in `<main>': undefined method `method_defined' for MyModule:Module (NoMethodError)

您可能想要的是respond_to?

档案m.rb

class AppSuperClass
end

module MyModule
  class MyClass < AppSuperClass
    def initialize
      puts "Hello"
    end
  end

  def self.create_class
    return MyClass.new
  end

  def mm
  end
end

档案t.rb

require_relative 'm'

class MyClass
    include MyModule
end

puts "you can send create_class to MyModule because it's a singleton (class) method"
puts "MyModule.respond_to?(:create_class) => #{MyModule.respond_to?(:create_class)}"

puts 'mm is not a singleton method of MyModule'
puts "MyModule.respond_to?(:mm) => #{MyModule.respond_to?(:mm)}"

puts 'mm is an instance method of MyClass, cannot be sent to MyClass'
puts "MyClass.respond_to?(:mm) => #{MyClass.respond_to?(:mm)}"

puts 'mm is an instance method of MyClass, can be sent to an instance of MyClass'
puts "MyClass.new.respond_to?(:mm) => #{MyClass.new.respond_to?(:mm)}"

puts "instance methods of MyModule : #{MyModule.instance_methods}"

puts "MyModule.method_defined?(:create_class) => #{MyModule.method_defined?(:create_class)}"
puts "MyModule.method_defined?(:mm) => #{MyModule.method_defined?(:mm)}"

puts "singleton methods of MyModule : #{MyModule.singleton_methods}"

module MyModule
    class << self
        puts 'we are in the singleton class / eigenclass'
        puts "method_defined?(:create_class) => #{method_defined?(:create_class)}"
    end
end

执行:

$ ruby -w t.rb 
you can send create_class to MyModule because it's a singleton (class) method
MyModule.respond_to?(:create_class) => true
mm is not a singleton method of MyModule
MyModule.respond_to?(:mm) => false
mm is an instance method of MyClass, cannot be sent to MyClass
MyClass.respond_to?(:mm) => false
mm is an instance method of MyClass, can be sent to an instance of MyClass
MyClass.new.respond_to?(:mm) => true
instance methods of MyModule : [:mm]
MyModule.method_defined?(:create_class) => false
MyModule.method_defined?(:mm) => true
singleton methods of MyModule : [:create_class]
we are in the singleton class / eigenclass
method_defined?(:create_class) => true