AttrPlus
ClassAttr
Adds class_attr_accessor
(and reader/writer) and inheritable_class_attr_accessor
(and
reader/writer of course) to Class.
require 'attr_plus'
class Polygon
class_attr_accessor :sides
end
Polygon.sides = 5
Polygon.sides #=> 5
class Square < Polygon
end
Square.sides #=> nil
class InheritablePolygon
inheritable_class_attr_accessor :sides
end
Polygon.sides = 4
class NewSquare < Polygon
end
Square.sides #=> 4
You can provide default values using a hash with :default set for the last value, or if just
creating one accessor/reader/writer add => defaultvalue
to the end, this example should
make it more clear:
require 'attr_plus/class'
class Person
class_attr_accessor :name => 'John Doe'
inheritable_class_attr_accessor :arms, :legs, :default => 2
inheritable_class_attr_accessor :fingers, :toes, :default => 5
end
class Agent < Person
@name = "James Bond"
end
Person.name #=> "John Doe"
Person.arms #=> 2
Person.toes #=> 5
Agent.name #=> "James Bond"
Agent.legs #=> 2
ModuleAttr
Almost exactly the same as class_*
but for modules.
require 'attr_plus/module'
module MyHouse
module_attr_accessor :width, :height, :default => 200
module_attr_accessor :rooms => []
module_attr_accessor :number, :street, :city, :country
end
House.width = 500
House.rooms = [:living_room, :kitchen]
House.rooms.first #=> :living_room
Instance Extensions
I've also added extensions to the methods for creating accessors on instances. These create
private versions, working exactly the same in every other way.
require 'attr_plus/instance'
class SecretBox
attr_writer :stuff
private_attr_reader :stuff
def initialize
@stuff = []
end
def <<(val)
stuff << val
end
def shake
stuff[rand(stuff.size)]
end
end
box = SecretBox.new
box << "giraffe"
box << "elephant"
box << "camel"
box << "cat"
p box.shake #=> "giraffe"
p box.stuff # NoMethodError: private method 'stuff' called
box.stuff = %w(dog hamster fish)
p box.shake #=> "fish"
And then as usual there are private_attr_accessor
and private_attr_writer
which work
as expected.
HashAttr
You can now access specific keys of a hash using hash_attr_*
or class_hash_attr_*
. The
normal version will get the variable in an instance but the class version works at the class
level, for example,
require_relative 'lib/attr_plus/hash'
class SomeApp
@config = {:name => 'SomeApp', :version => '3.1.7'}
class_hash_attr_accessor :@config, :name, :version
def self.config; @config; end
end
p SomeApp.config #=> {:name => 'SomeApp', :version => '3.1.7'}
SomeApp.name = 'CoolApp'
p SomeApp.name #=> 'CoolApp'
SomeApp.version = '4.0.0'
p SomeApp.config #=> {:name => 'CoolApp', :version => '4.0.0'}
Uses the class versions, but it could easily be written using the normal versions (probably
the most usual way):
class AnApp
def initialize
@config = {}
end
hash_attr_accessor :@config, :name, :version
attr_accessor :config
end
some_app = AnApp.new
some_app.name = 'AnotherApp'
some_app.version = '1.5.0'
p some_app.config #=> {:name => 'AnotherApp', :version => '1.5.0'}
In both of these I've passed the instance variable as a symbol as the argument to get the hash
but I could have used just :config
as I have create the methods in each. If the hash uses
string keys just pass the arguments to .hash_attr_
as strings instead of symbols.
Install
$ (sudo) gem install attr_plus
Use
require 'attr_plus'
# OR for specific methods
require 'attr_plus/class' # for only class_*
require 'attr_plus/module' # for only module_*
require 'attr_plus/hash' # for only hash_*
require 'attr_plus/instance' # for only private_attr_*
Important!
If in a class you define the self.inherited
method, make sure to call super
somewhere otherwise default values will not be set for the subclass.
Thanks
Copyright
Copyright (c) 2010 Joshua Hawxwell. See LICENSE for details.