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