The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Ruby: instance and class methods from a module

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Jay Fields

Posts: 765
Nickname: jayfields
Registered: Sep, 2006

Jay Fields is a software developer for ThoughtWorks
Ruby: instance and class methods from a module Posted: Dec 17, 2006 8:56 AM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Jay Fields.
Original Post: Ruby: instance and class methods from a module
Feed Title: Jay Fields Thoughts
Feed URL: http://blog.jayfields.com/rss.xml
Feed Description: Thoughts on Software Development
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Jay Fields
Latest Posts From Jay Fields Thoughts

Advertisement
Context: You have a presenter class that needs to validate attributes. You like the way ActiveRecord allows you to define validations using class methods. You also want to use a valid? method on your presenter instances to determine if they are valid or not.

Step one: You define the validation methods in a module.
module Presenters::Validations
def validates_presence_of(*args)
..
end

def validates_format_of(*args)
..
end
end
Then, you extend the module to add the class methods to your presenter.
class AccountInformationPresenter
extend Presenters::Validations

validates_presence_of :username, :password
..
This implementation also requires that you define valid? in each presenter class.
  def valid?
self.class.validations.collect do |validation|
unless validation.valid?(self)
self.errors.add(validation.on, validation.message)
end
end.all?
end
end
When building the second presenter it should be clear that the valid? should be abstracted. This abstraction could result in another module. The new module could be included thus providing valid? as an instance method.

Step two: Another common approach is to define the class methods in a ClassMethods module inside the Presenters::Validations module.
module Presenters::Validations
module ClassMethods
def validates_presence_of(*args)
..
end

def validates_format_of(*args)
..
end
end

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

def valid?
self.class.validations.collect do |validation|
unless validation.valid?(self)
self.errors.add(validation.on, validation.message)
end
end.all?
end
end
This approach, while common in Rails, can generate some dislike. A counter argument is that include is designed to add instance methods and using self.included is clever, but provides unexpected behavior. I've found that people who dislike the self.included trick prefer to explicitly use both include and extend.
class AccountInformationPresenter
include Presenter::Validations
extend Presenter::Validations::ClassMethods

..
end
Which approach is better?
I tend to prefer explicitness; however, if something is used often enough it can turn from an anti-pattern to an idiom. I'm not sure if that is the case or not here, but I think it might be.

Read: Ruby: instance and class methods from a module

Topic: JRuby 0.92 released Previous Topic   Next Topic Topic: Why I still look at the jroller homepage sometimes

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use