Module: KeyStruct

Defined in:
lib/key_struct/version.rb,
lib/key_struct/key_struct.rb

Defined Under Namespace

Classes: Base

Constant Summary collapse

VERSION =
"0.4.1"

Class Method Summary collapse

Class Method Details

.accessor(*keys) ⇒ Object



7
8
9
# File 'lib/key_struct/key_struct.rb', line 7

def self.accessor(*keys)
  fetch_key_struct(:accessor, keys)
end

.define_key_struct(access, keys) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/key_struct/key_struct.rb', line 88

def self.define_key_struct(access, keys) 
  keys = keys.dup
  defaults = (Hash === keys.last) ? keys.pop.dup : {}
  keys += defaults.keys

  Class.new(Base).tap{ |klass|
    klass.class_eval do
      @keys = keys
      @defaults = defaults
      @access = access
      send "attr_#{access}", *keys
    end
  }
end

.fetch_key_struct(access, keys) ⇒ Object

for anonymous superclasses, such as

  class Foo < KeyStruct[:a, :b]
  end

we want to be sure that if the code gets re-executed (e.g. the file
gets loaded twice) the superclass will be the same object otherwise
ruby will raise a TypeError: superclass mismatch.  So keep a cache of
anonymous KeyStructs

But don't reuse the class if it has a name, i.e. if it was assigned to
a constant.  If somebody does

   Foo = KeyStruct[:a, :b]
   Bar = KeyStruct[:a, :b]

they should get different class definitions, in particular because the
classname is used in #to_s and #inspect


81
82
83
84
85
86
# File 'lib/key_struct/key_struct.rb', line 81

def self.fetch_key_struct(access, keys)
  @cache ||= {}
  signature = [access, keys]
  @cache.delete(signature) if @cache[signature] and @cache[signature].name
  @cache[signature] ||= define_key_struct(access, keys)
end

.reader(*keys) ⇒ Object



3
4
5
# File 'lib/key_struct/key_struct.rb', line 3

def self.reader(*keys)
  fetch_key_struct(:reader, keys)
end