Adding class method through included module?

I

ivdkleyn

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
 
R

Robert Klemme

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 Testvalidate_members: [:attr1, :attr2]
rule_set: :strict
=> nil

Kind regards

robert
 
S

Stefan Lang

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>
 
I

Iwan van der Kleyn

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
 
R

Robert Klemme

Iwan van der Kleyn said:
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
validate_members: [:attr1, :attr2]
rule_set: :strict
=> nil=> [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
validate_members: [:attr1, :attr2]
rule_set: :strict
=> nilvalidate_members: [:attr1, :attr2]
rule_set: :strict
=> nil

Kind regards

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top