Created
June 18, 2010 15:05
-
-
Save mrrooijen/443747 to your computer and use it in GitHub Desktop.
A simple Ruby module that, when extended inside a class, will provide a method that will enable the creation of methods that could be used to create nice block-notation setters.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## | |
# AttrAccessorBlock | |
# | |
# This module is to be "extended" (not included) into a class | |
# Then just invoke the "attr_accessor_block" method, like you would with "attr_accessor" | |
# This will enable you to make use of "block notations" and "instance_eval" to create "prettier" | |
# and more "readable" attribute setters. | |
# | |
# class Example | |
# extend AttrAccessorBlock | |
# attr_accessor_block :example1, :example2, :example3, :etc | |
# end | |
# | |
module AttrAccessorBlock | |
def attr_accessor_block(*attributes) | |
attributes.each do |method| | |
define_method method do |*value| | |
if value = value.first | |
instance_variable_set("@#{method}", value) | |
else | |
instance_variable_get("@#{method}") | |
end | |
end | |
define_method "#{method}=" do |value| | |
instance_variable_set("@#{method}", value) | |
end | |
end | |
end | |
end | |
## | |
# Example Person Class | |
# Extend the class with AttrAccessorBlock (ClassMethods) | |
# Use the attr_accessor_block instead of the built-in attr_accessor | |
# | |
# attr_accessor_block creates 2 methods, like attr_accessor | |
# except that the "attribute()" method that's produced will act a bit different | |
# from the one you get with attr_accessor, the main difference being: | |
# - If no value is set, e.g. "person.name()", then the @name is returned | |
# - If a value is set, e.g. "person.name('Michael')", then the @name is set to 'Michael' | |
# This is to allow for prettier block configurations. Other than that, it practically works the same | |
# as attr_accessor, you can still also use person.name = 'Michael' | |
class Person | |
## | |
# Extend the "AttrAccessorBlock" module | |
extend AttrAccessorBlock | |
## | |
# Define some methods to dynamically generate like you would with "attr_accessor" | |
attr_accessor_block :name, :age, :gender | |
## | |
# For Example 1 | |
def update_example_1 | |
yield self | |
end | |
## | |
# For Example 2 and 3 | |
def update_example_2_and_3(&block) | |
instance_eval &block | |
end | |
end | |
## | |
# Example 1 with "object.attribute = value" | |
person = Person.new | |
person.update_example_1 do |object| | |
object.name = 'Michael' | |
object.age = 21 | |
object.gender = 'Male' | |
end | |
puts person.name, person.age, person.gender | |
## | |
# Example 2 with "object.attribute value" | |
person = Person.new | |
person.update_example_2_and_3 do |object| | |
object.name 'Michael' | |
object.age 21 | |
object.gender 'Male' | |
end | |
puts person.name, person.age, person.gender | |
## | |
# Example 3 with "attribute value" | |
person = Person.new | |
person.update_example_2_and_3 do | |
name 'Michael' | |
age 21 | |
gender 'Male' | |
end | |
puts person.name, person.age, person.gender |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment