Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
attr_accessor for class level instance variables.
Ruby
Branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
lib
spec
.gitignore
LICENSE
README.md
attr_plus.gemspec

README.md

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.

Something went wrong with that request. Please try again.