Module: ClassX

Defined in:
lib/classx.rb,
lib/classx/declare.rb,
lib/classx/attribute.rb,
lib/classx/attributes.rb,
lib/classx/bracketable.rb,
lib/classx/commandable.rb,
lib/classx/role/logger.rb,
lib/classx/class_attributes.rb

Overview

usage

require 'classx'
class Point
  include ClassX

  has :x, :kind_of => Fixnum
  has :y, :kind_of => Fixnum
end

class Point3D < Point
  has :z, :kind_of => Fixnum, :optional => true
end

Point.new(:x => 30, :y => 40)  #=> <# Point @x=30, @y=40 >
point3d = Point3D.new(:x => 30, :y => 40, :z => 50)  #=> <# Point3D @x=30, @y=40, @z=50 >
point3d.z = 60.0 # raise ClassX::InvalidAttrArgument

Defined Under Namespace

Modules: AttributeMethods, Attributes, Bracketable, ClassAttributes, ClassMethods, Commandable, Declare, Role, Validate Classes: AttrRequiredError, AttributeFactory, InstanceException, InvalidAttrArgument, LazyOptionShouldHaveDefault, OptionalAttrShouldBeWritable, RequiredAttrShouldNotHaveDefault

Constant Summary collapse

MODULE_USAGE_MAP_OF =
{
  :ClassAttributes => :extend,
  :CAttrs => :extend,
  :Commandable => :extend,
  :Declare     => :extend,
  :Bracketable => :include,
  :Validate => :include,
}
UNSERIALIZE_INSTANCE_VARIABLES =
["@__attribute_of", "@__attribute_data_of"]
CAttrs =

alias for lazy people.

ClassAttributes

Instance Method Summary collapse

Instance Method Details

#==(other) ⇒ Object

shared implementation for comparing classx based object.



114
115
116
117
118
119
# File 'lib/classx.rb', line 114

def == other
  return false unless other.kind_of? self.class
  attribute_of.all? do |key, val|
    val.get == other.__send__(key)
  end
end

#after_initObject

automatically called this method on last of #initialize. you can override this method.



110
111
# File 'lib/classx.rb', line 110

def after_init
end

#attribute_ofObject

return Hash of attribute’s name as a key and attribute’s meta class instance as a value. for example,

class YourClass
   include ClassX
   has :x
end

obj = YourClass.new(:x => 10)
obj.attribute_of    #=> { "x" => <#<ClassX::Attribute> parent=<# YourClass> ... > }


95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/classx.rb', line 95

def attribute_of
  unless instance_variable_defined?('@__attribute_of') && @__attribute_of
    @__attribute_of = {}
    if self.class.attribute_of
      self.class.attribute_of.keys.each do |key|
        @__attribute_of[key] = __send__ "attribute_of:#{key}"
      end
    end
  end

  @__attribute_of
end

#dupObject

dupping classx based class.



135
136
137
# File 'lib/classx.rb', line 135

def dup
  self.class.new(to_hash)
end

#initialize(*args) ⇒ Object

*args is Hash in default. Hash should have attribute’s key and valid value for attribute. This method checking required value is setted and taking value is valid to attribute.



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/classx.rb', line 52

def initialize *args
  if respond_to? :before_init
    warn 'before_init is deprecated. please define process_init_args class method'
  else
    hash = self.class.process_init_args(*args)
  end

  unless hash && hash.kind_of?(Hash)
    raise ArgumentError, "#{hash.inspect} was wrong as arguments. please specify kind of Hash instance"
  end

  # allow String or Symbol for key
  tmp_hash = {}
  hash.each do |key,val|
    tmp_hash[key.to_s] = val
  end
  hash = tmp_hash

  hash.each do |key, val|
    if attribute_of[key]
      attribute_of[key].set val
    end
  end

  attribute_of.each do |key, val|
    next if val.class.lazy?
    raise AttrRequiredError, "param: :#{key} is required to #{hash.inspect}" if !val.class.optional? && val.get.nil?
  end

  after_init
end

#marshal_dumpObject

for Marshal.dump



140
141
142
143
144
145
146
147
148
149
# File 'lib/classx.rb', line 140

def marshal_dump
  dump_of = {}
  dump_of[:attribute_of] = to_hash
  dump_of[:instance_variable_of] = {}
  ( instance_variables.map {|ival| ival.to_s } - UNSERIALIZE_INSTANCE_VARIABLES ).each do |ival|
    dump_of[:instance_variable_of][ival] = instance_variable_get(ival)
  end

  dump_of
end

#marshal_load(val) ⇒ Object

for Marshal.load



152
153
154
155
156
157
158
159
# File 'lib/classx.rb', line 152

def marshal_load val
  self.attribute_of.each do |k, v|
    v.set(val[:attribute_of][k])
  end
  val[:instance_variable_of].each do |key, val|
    instance_variable_set(key, val)
  end
end

#to_hashObject

convert attribute key and value to Hash.



124
125
126
127
128
129
130
131
132
# File 'lib/classx.rb', line 124

def to_hash
  result = {}

  attribute_of.each do |key, val|
    result[key] = val.get
  end

  result
end

#to_yaml(opts = {}) ⇒ Object

for YAML.dump



162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/classx.rb', line 162

def to_yaml opts={}
  require 'yaml'
  YAML.quick_emit(self, opts) do |out|
    out.map( taguri, to_yaml_style ) do |map|
      attribute_of = {}
      to_hash.each do |key, val|
        attribute_of[key] = val
      end
      map.add(:attribute_of, attribute_of)

      instance_variable_of = {}
      ( instance_variables.map {|ival| ival.to_s } - UNSERIALIZE_INSTANCE_VARIABLES ).each do |ival|
        instance_variable_of[ival] = instance_variable_get(ival)
      end
      map.add(:instance_variable_of, instance_variable_of)
    end
  end
end

#yaml_initialize(tag, val) ⇒ Object

for YAML.load



182
183
184
185
186
187
188
189
190
# File 'lib/classx.rb', line 182

def yaml_initialize tag, val
  self.attribute_of.each do |k, v|
    v.set(val[:attribute_of][k])
  end

  val[:instance_variable_of].each do |k, v|
    instance_variable_set(k, v)
  end
end