Home > other >  Undefined Method on Include Module Ruby
Undefined Method on Include Module Ruby

Time:10-17

I have this class Callback to act as custom attr_accessor

module Callback
  def add_callback(name)
    define_method(name) do
      instance_variable_get("@#{name.to_s}")
    end

    define_method("#{name.to_s}=") do |value|
      instance_variable_set("@#{name.to_s}", value)
    end
  end
end

I do include the class into my main class

require_relative "./callback"
class TaskManager
  include Callback
  add_callback :on_start, :on_finished, :on_error

  def initialize; end
end

But when I require it in irb I got undefined method error

require "./task_manager.rb"
irb(main):003:0> require "./task_manager.rb"
/Users/task_manager.rb:9:in `<class:TaskManager>': undefined method `add_callback' for TaskManager:Class (NoMethodError)

Both file already in same folder

CodePudding user response:

You don't need to use getter and setter explicitly, there is attr_accessor in Ruby

If your initialize is empty you can omit it

module Callback
  def add_callback(*attr_names)
    attr_accessor(*attr_names)
  end
end

class TaskManager
  extend Callback
  add_callback :on_start, :on_finished, :on_error
end
task_manager = TaskManager.new
task_manager.on_start = 10
task_manager.on_start # => 10

BTW you also don't need to use to_s for object in string interpolation (it will be applied automatically) in your "@#{name.to_s}"

CodePudding user response:

You can resolved the issue like below

module Callback
  def add_callback(*attr_names)
    attr_names.each do |name|  
        define_method(name) do
          instance_variable_get("@#{name.to_s}")
        end
    
        define_method("#{name.to_s}=") do |value|
          instance_variable_set("@#{name.to_s}", value)
        end
    end
  end
end
class TaskManager
  extend Callback
  add_callback :on_start, :on_finished, :on_error

  def initialize; end
end

When you include a module into a class, the module methods are imported as instance methods.

However, when you extend a module into a class, the module methods are imported as class methods.

Also please have a look blow answer for more detail

What is the difference between include and extend in Ruby?

Need to use variable number of arguments like below

def add_callback(*attr_names); end

because of calling of method use multiple arguments

  add_callback :on_start, :on_finished, :on_error
  •  Tags:  
  • ruby
  • Related