[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Adding class method through included module?

ivdkleyn

2/22/2005 11:02:00 AM

Hi there,

I've written an "Validation" module. Problem is that I would like to
add a class method to the class in which the module is included, and
not just an instance method.

For example: by including a module I would be able to call added
class-methods like in the following example

class Test
include Validation
validate_members :attr1, :attr2
rule_set :strict
end

Well, that doesn;t work (Ruby protests about instance methods which
cannot be found).

So therefore my question: how would I be able to add class methods to a
class through a Module?

Regards,

Iwan

4 Answers

Robert Klemme

2/22/2005 12:20:00 PM

0


<ivdkleyn@gmail.com> schrieb im Newsbeitrag
news:1109070093.394927.4290@z14g2000cwz.googlegroups.com...
> Hi there,
>
> I've written an "Validation" module. Problem is that I would like to
> add a class method to the class in which the module is included, and
> not just an instance method.
>
> For example: by including a module I would be able to call added
> class-methods like in the following example
>
> class Test
> include Validation
> validate_members :attr1, :attr2
> rule_set :strict
> end
>
> Well, that doesn;t work (Ruby protests about instance methods which
> cannot be found).
>
> So therefore my question: how would I be able to add class methods to a
> class through a Module?

module Validation
def self.included(cl)
def cl.validate_members(*a) puts "validate_members: #{a.inspect}" end
def cl.rule_set(set) puts "rule_set: #{set.inspect}" end
end
end

?> class Test
>> include Validation
>> validate_members :attr1, :attr2
>> rule_set :strict
>> end
validate_members: [:attr1, :attr2]
rule_set: :strict
=> nil

Kind regards

robert

Stefan Lang

2/22/2005 5:34:00 PM

0

ivdkleyn@gmail.com wrote:

> Hi there,
>
> I've written an "Validation" module. Problem is that I would like to
> add a class method to the class in which the module is included, and
> not just an instance method.
>
> For example: by including a module I would be able to call added
> class-methods like in the following example
>
> class Test
> include Validation
> validate_members :attr1, :attr2
> rule_set :strict
> end
>
> Well, that doesn;t work (Ruby protests about instance methods which
> cannot be found).
>
> So therefore my question: how would I be able to add class methods to a
> class through a Module?
>
> Regards,
>
> Iwan

You could include the module for your class object:

irb(main):001:0> module Validation
irb(main):002:1> def validate_members(*symbols)
irb(main):003:2> # do something with symbols
irb(main):004:2* end
irb(main):005:1> end
=> nil
irb(main):006:0> class Test
irb(main):007:1> class << self
irb(main):008:2> include Validation
irb(main):009:2> # more class methods
irb(main):010:2* end
irb(main):011:1> validate_members :attr1, :attr2
irb(main):012:1> end
=> nil
irb(main):013:0>

Yuu

2/22/2005 7:47:00 PM

0


>>So therefore my question: how would I be able to add class methods to a
>>class through a Module?

> module Validation
> def self.included(cl)
> def cl.validate_members(*a) puts "validate_members: #{a.inspect}" end
> def cl.rule_set(set) puts "rule_set: #{set.inspect}" end
> end
> end

Works like a charm. Thanks! This one I completely overlooked in the
Pickaxe book.

Iwan

Robert Klemme

2/23/2005 9:02:00 AM

0


"Iwan van der Kleyn" <none@none.net> schrieb im Newsbeitrag
news:421B8C3F.8010300@none.net...
>
> >>So therefore my question: how would I be able to add class methods to
a
> >>class through a Module?
>
> > module Validation
> > def self.included(cl)
> > def cl.validate_members(*a) puts "validate_members: #{a.inspect}"
end
> > def cl.rule_set(set) puts "rule_set: #{set.inspect}" end
> > end
> > end
>
> Works like a charm. Thanks! This one I completely overlooked in the
> Pickaxe book.

Additional note: if you want to be more flexible and more efficient you
can do this:

module Validation
module ClassMethods
def validate_members(*a) puts "validate_members: #{a.inspect}" end
def rule_set(set) puts "rule_set: #{set.inspect}" end
end

def self.included(cl) cl.extend ClassMethods end
end

>> class Test
>> include Validation
>> validate_members :attr1, :attr2
>> rule_set :strict
>> end
validate_members: [:attr1, :attr2]
rule_set: :strict
=> nil
>> class <<Test; ancestors end
=> [Validation::ClassMethods, Class, Module, Object, Kernel]

Advantage is that you have only one definition of those class methods plus
you can change them later.

And if you want to make that recursively work, just do this:

module Validation
module ClassMethods
def validate_members(*a) puts "validate_members: #{a.inspect}" end
def rule_set(set) puts "rule_set: #{set.inspect}" end

# this is the crucial bit:
def inherited(cl) cl.extend ClassMethods end
end

def self.included(cl) cl.extend ClassMethods end
end

>> class Test
>> include Validation
>> validate_members :attr1, :attr2
>> rule_set :strict
>> end
validate_members: [:attr1, :attr2]
rule_set: :strict
=> nil
>> class DerivedTest < Test
>> validate_members :attr1, :attr2
>> rule_set :strict
>> end
validate_members: [:attr1, :attr2]
rule_set: :strict
=> nil

Kind regards

robert