I have a module of following
module SimpleTask
def task1
end
def task2
end
def task3
end
end
And I have a model which r
A simple solution for this is
define_method :task2, SimpleTask.instance_method(:task2)
It sounds like you need to refactor #task2
into a separate module (e.g., BaseTask
). Then you can easily include only BaseTask
where you only need #task2
.
module BaseTask
def task2
...
end
end
module SimpleTask
include BaseTask
def task1
...
end
def task3
...
end
end
It's hard to help much more without a more concrete question (such as interdependence between the methods of SimpleTask
, etc.
You could do some meta-programming where you include SimpleTask
and then undefine the methods you don't want, but that's pretty ugly IMO.
You could add
module SimpleTask
def task1
end
def task2
end
def task3
end
module_function :task2
end
So that you can call the method like a class method on the module as well as having it as an instance method in the places you do want all three methods, ie:
class Foo
include SimpleTask
end #=> Foo.new.task2
class LessFoo
def only_needs_the_one_method
SimpleTask.task2
end
end #=> LessFoo.new.only_needs_the_one_method
Or, if there's really no shared state in the module and you don't mind always using the module name itself, you can just declare all the methods class-level like so:
module SimpleTask
def self.task1
end
def self.task2
end
def self.task3
end
end
class Foo
include SimpleTask # Does, more or less nothing now
def do_something
SimpleTask.task1
end
end
#=> Foo.new.task2 #=> "task2 not a method or variable in Foo"
#=> Foo.new.do_something does, however, work
class LessFoo
def only_needs_the_one_method
SimpleTask.task2
end
end #=> LessFoo.new.only_needs_the_one_method works as well in this case
But you'd have to change all the callers in that case.
I'm going to steal an example from delegate.rb, it restricts what it includes
...
class Delegator < BasicObject
kernel = ::Kernel.dup
kernel.class_eval do
[:to_s,:inspect,:=~,:!~,:===,:<=>,:eql?,:hash].each do |m|
undef_method m
end
end
include kernel
...
becomes
module PreciseInclude
def include_except(mod, *except)
the_module = mod.dup
the_module.class_eval do
except.each do |m|
remove_method m # was undef_method, that prevents parent calls
end
end
include the_module
end
end
class Foo
extend PreciseInclude
include_except(SimpleTask, :task1, :task2)
end
Foo.instance_methods.grep(/task/) => [:task3]
you can always flip it so instead of include it becomes include_only
The catch is that remove_method won't work for nested modules, and using undef will prevent searching the entire hierarchy for that method.