Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Conditionally Including Methods From A Module?

Reply
Thread Tools

Conditionally Including Methods From A Module?

 
 
Kenny
Guest
Posts: n/a
 
      10-25-2008
Is there a way to include only certain methods from a module instead
of all the methods?

Given the following:

module ActsAsAnything
def self.included(base)
base.extend(ClassMethods)
end

module ClassMethods
def acts_as_anything(opts = {})
# Based on the options based in, I would like to selectively
include certain methods from
# the InstanceMethods module.

# Something like:
include ActsAsAnything::InstanceMethods.instance_method(:i ndex)
if opts[:include_index]
include ActsAsAnything::InstanceMethods.instance_method(:l ist)
if opts[:include_list]

# (Note the 'if' condition above is just for example.... )
end
end

module InstanceMethods
def index
# .....
end

def list
# ....
end
end
end

However, 'include' requires a module and I can't figure out the proper
syntax, or even if this is possible, to just include a certain method
from it. The is for a standard acts_as_.... Rails plug-in.

Any help or guidance is much appreciated.

Sincerely,
Kenny
 
Reply With Quote
 
 
 
 
Mike Gold
Guest
Posts: n/a
 
      10-25-2008
Kenny wrote:
> Is there a way to include only certain methods from a module instead
> of all the methods?


Not directly. In general, methods are part of the same module for a
reason. A given method may call other methods in the module, and a
method may use instance variables defined in other methods.

What you propose could make sense in the case of a "pure utility" module
which has no state and where there little is or no relationship between
the methods.

def methods_to_lambdas(mod)
instance = Class.new { include mod }.new
mod.instance_methods(false).inject(Hash.new) { |hash, meth|
hash.update(
meth.to_sym => lambda { |*args, &block|
instance.send(meth, *args, &block)
}
)
}
end

def pull_methods(mod, *names)
lambdas = methods_to_lambdas(mod)
names.each { |name|
define_method(name, &lambdas[name])
}
end

module Misc
def func_a ; p "Misc#func_a" ; end
def func_b ; p "Misc#func_b" ; end
def func_c ; p "Misc#func_c" ; end
end

class Fred
pull_methods(Misc, :func_a, :func_b)
end

Fred.new.func_a #=> Misc#func_a
Fred.new.func_b #=> Misc#func_b
Fred.new.func_c #=> NoMethodError

ruby-1.8.7 or 1.9 is needed for the lambda syntax (for 1.8.6 you can
eval a string instead).
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
 
 
 
Kenny
Guest
Posts: n/a
 
      10-25-2008
Thanks so much for the post Mike, very much appreciated and a great
learning lesson for me in some lower level Ruby semantics.

After my post last night, I can up with using define_method as well
and produced something like the following:

module ActsAsAnything
def self.included(base)
base.extend(ClassMethods)
end

module ClassMethods
# acts_as_anything
def acts_as_anything(opts = {})

# index
define_method(:index) do
puts 'Index Method'
end if opts.include?(:index)
end
end
end

Since I'm including a Module that I'm the author of, I figure I can
get away with this syntax and just redefine my top level Module as
such.

Any thoughts on this implementation?

Sincerely,
Kenny
 
Reply With Quote
 
Daniel Berger
Guest
Posts: n/a
 
      10-26-2008
On Oct 25, 3:04=A0am, Kenny <(E-Mail Removed)> wrote:
> Is there a way to include only certain methods from a module instead
> of all the methods?


<snip>

Yep.

gem install use

class Foo
use ModuleA, :include =3D> [:method_x]
end

That will only include 'method_x' from ModuleA. You can also exclude
and alias included methods on the fly.

Regards,

Dan

 
Reply With Quote
 
Daniel Berger
Guest
Posts: n/a
 
      01-08-2009
Kenny wrote:
> Is there a way to include only certain methods from a module instead
> of all the methods?
>
> Given the following:
>
> module ActsAsAnything
> def self.included(base)
> base.extend(ClassMethods)
> end
>
> module ClassMethods
> def acts_as_anything(opts = {})
> # Based on the options based in, I would like to selectively
> include certain methods from
> # the InstanceMethods module.
>
> # Something like:
> include ActsAsAnything::InstanceMethods.instance_method(:i ndex)
> if opts[:include_index]
> include ActsAsAnything::InstanceMethods.instance_method(:l ist)
> if opts[:include_list]
>
> # (Note the 'if' condition above is just for example.... )
> end
> end
>
> module InstanceMethods
> def index
> # .....
> end
>
> def list
> # ....
> end
> end
> end
>
> However, 'include' requires a module and I can't figure out the proper
> syntax, or even if this is possible, to just include a certain method
> from it. The is for a standard acts_as_.... Rails plug-in.
>
> Any help or guidance is much appreciated.


gem install use

class Foo
use Bar, :method_a, :method_b
end

See http://rubyforge.org/docman/view.php.../examples.html for more
examples.

Regards,

Dan

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Is there a way to find the class methods of a class, just like'methods' finds the instance methods? Kenneth McDonald Ruby 5 09-26-2008 03:09 PM
Conditionally including a file Craig ASP .Net 2 11-08-2005 11:21 AM
Conditionally display excluding / including tax? Olav Tollefsen ASP .Net 2 02-01-2005 05:43 AM
Including .htm files conditionally? Sten Westerback ASP General 2 02-03-2004 05:14 PM
including singleton methods with a module? Ferenc Engard Ruby 2 12-31-2003 01:54 PM



Advertisments