Module: OpenStructable

Defined in:
lib/mixers/ostructable.rb

Overview

Ostructable

OpensStructable is a mixin module which can provide OpenStruct behavior to any class or object. OpenStructable allows extention of data objects with arbitrary attributes.

Usage

require 'ostructable'

class Record
  include OpenStructable
end

record = Record.new
record.name    = "John Smith"
record.age     = 70
record.pension = 300

puts record.name     # -> "John Smith"
puts record.address  # -> nil

– TODO: Keep this uptodate with ostruct.rb

TODO: As with OpenStruct, marshalling is problematic at the moment. ++

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(mid, *args) ⇒ Object

:nodoc:



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/mixers/ostructable.rb', line 77

def method_missing(mid, *args) # :nodoc:
  mname = mid.to_s
  len = args.length
  if mname =~ /=$/
    if len != 1
      raise ArgumentError, "wrong number of arguments (#{len} for 1)", caller(1)
    end
    if self.frozen?
      raise TypeError, "can't modify frozen #{self.class}", caller(1)
    end
    mname.chop!
    @__table__ ||= {}
    @__table__[mname.intern] = args[0]
    self.new_ostruct_member(mname)
  elsif len == 0
    @__table__ ||= {}
    @__table__[mid]
  else
    raise NoMethodError, "undefined method `#{mname}' for #{self}", caller(1)
  end
end

Instance Method Details

#==(other) ⇒ Object

Compare this object and other for equality.



124
125
126
127
# File 'lib/mixers/ostructable.rb', line 124

def ==(other)
  return false unless(other.kind_of?(OpenStruct))
  return @__table__ == other.table
end

#delete_field(name) ⇒ Object

Remove the named field from the object.



102
103
104
105
# File 'lib/mixers/ostructable.rb', line 102

def delete_field(name)
  @__table__ ||= {}
  @__table__.delete name.to_sym
end

#initialize(hash = nil) ⇒ Object



31
32
33
34
35
36
37
38
39
# File 'lib/mixers/ostructable.rb', line 31

def initialize(hash=nil)
  @__table__ = {}
  if hash
    for k,v in hash
      @__table__[k.to_sym] = v
      new_ostruct_member(k)
    end
  end
end

#initialize_copy(orig) ⇒ Object

duplicate an OpenStruct object members.



42
43
44
45
# File 'lib/mixers/ostructable.rb', line 42

def initialize_copy(orig)
  super
  @__table__ = @__table__.dup
end

#inspectObject

Returns a string containing a detailed summary of the keys and values.



110
111
112
113
114
115
116
# File 'lib/mixers/ostructable.rb', line 110

def inspect
  str = "<#{self.class}"
  for k,v in (@__table__ ||= {})
    str << " #{k}=#{v.inspect}"
  end
  str << ">"
end

#marshal_dumpObject



47
48
49
# File 'lib/mixers/ostructable.rb', line 47

def marshal_dump
  @table
end

#marshal_load(x) ⇒ Object



50
51
52
53
# File 'lib/mixers/ostructable.rb', line 50

def marshal_load(x)
  @table = x
  @table.each_key{|key| new_ostruct_member(key)}
end

#new_ostruct_member(name) ⇒ Object



55
56
57
58
59
60
61
62
# File 'lib/mixers/ostructable.rb', line 55

def new_ostruct_member(name)
  unless self.respond_to?(name)
    self.instance_eval %{
      def #{name}; @__table__[:#{name}]; end
      def #{name}=(x); @__table__[:#{name}] = x; end
    }
  end
end

#update(hash) ⇒ Object

Generate additional attributes and values.



67
68
69
70
71
72
73
74
75
# File 'lib/mixers/ostructable.rb', line 67

def update(hash)
  @__table__ ||= {}
  if hash
    for k,v in hash
      @__table__[k.to_sym] = v
      new_ostruct_member(k)
    end
  end
end