Class: Object

Inherits:
BasicObject
Defined in:
lib/traits.rb,
lib/traits-0.10.0.rb

Instance Method Summary collapse

Instance Method Details

#__trait_arg_filter(*args, &block) ⇒ Object

–}}}

Raises:

  • (ArgumentError)


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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/traits.rb', line 57

def __trait_arg_filter(*args, &block)
#--{{{
  pre = nil
  post = nil
  validate = nil
  cast = nil
  munge = nil
  type = nil
  ducktype = nil
  default = nil
  names_and_defaults = nil
  toggle = nil

  if block and not block.respond_to? :__trait_default
    block.__trait_singleton_class.class_eval{ attr '__trait_default' }
  end

  list = [ args ].flatten.dup
  opts = Hash::new.update(((list.size > 1 and Hash === list.last) ? list.pop : {}))

  pre = __trait_getopt opts, 'pre'
  post = __trait_getopt opts, 'post'
  validate = __trait_getopt opts, 'validate'
  cast = __trait_getopt opts, 'cast'
  munge = __trait_getopt opts, 'munge'
  type = __trait_getopt(opts, 'type', __trait_getopt(opts, 'case'))
  ducktype = __trait_getopt opts, 'ducktype'
  default = __trait_getopt opts, 'default'
  toggle = __trait_getopt opts, 'toggle'

  list, hashes = list.partition{|arg| not Hash === arg}
  hashes << opts unless opts.empty? # in which case it was not, in fact, opts

  names_and_defaults = hashes.inject({}){|h,h2| h.update h2} 

  raise ArgumentError, 
    "cannot specify both 'default' keyword and 'default' block" if
      block and default

  default ||= block

  # force list and names_and_defaults.keys to strings
  list = list.map{|t| "#{ t }"}
  #names_and_defaults = Hash[ *names_and_defaults.to_a.map{|k,v| ["#{ k }", v]}.flatten ]
  h = names_and_defaults
  h.keys.each{|k| h[k.to_s] = h.delete(k)}

  list.each{|name| names_and_defaults[name] = default}

  names = list + (names_and_defaults.keys - list)

  hooks = {
    'pre' => pre, 
    'cast' => cast,
    'munge' => munge, 
    'type' => type,
    'ducktype' => ducktype,
    'validate' => validate, 
    'post' => post, 
    'toggle' => toggle,
  }

  names_and_hooks = names.inject({}){|h, name| h.update name => hooks}

  ret = {
    'names_and_defaults' => names_and_defaults,
    'names_and_hooks' => names_and_hooks,
  }
#--}}}
end

#__trait_define_singleton_reader_traits(*args, &block) ⇒ Object



173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/traits.rb', line 173

def __trait_define_singleton_reader_traits(*args, &block)
#--{{{
  argf = __trait_arg_filter args, &block
  defaults = __trait_singleton_method_defaults
  list = __trait_singleton_method_list 
  mhooks = __trait_singleton_method_hooks
  argf['names_and_defaults'].each do |name, default|
    __trait_singleton_class.__trait_define_reader_trait name, default, defaults, list
  end
  argf['names_and_hooks'].each{|name, hooks| mhooks[name].update hooks}
  __trait_search_path.map{|ta| ta.__trait_singleton_method_list['readers']}.flatten
#--}}}
end

#__trait_define_singleton_traits(*args, &block) ⇒ Object

–}}}



199
200
201
202
203
204
205
206
# File 'lib/traits.rb', line 199

def __trait_define_singleton_traits(*args, &block)
#--{{{
  writers = __trait_define_singleton_writer_traits(*args, &block)
  readers = __trait_define_singleton_reader_traits(*args, &block)
  wr = writers.inject({}){|h,k| h.update k.delete('=') => k}
  readers.map{|r| [r, wr[r]]}
#--}}}
end

#__trait_define_singleton_writer_traits(*args, &block) ⇒ Object

–}}}



186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/traits.rb', line 186

def __trait_define_singleton_writer_traits(*args, &block)
#--{{{
  argf = __trait_arg_filter args, &block
  defaults = __trait_singleton_method_defaults
  list = __trait_singleton_method_list 
  mhooks = __trait_singleton_method_hooks
  argf['names_and_defaults'].each do |name, default|
    __trait_singleton_class.__trait_define_writer_trait name, default, defaults, list
  end
  argf['names_and_hooks'].each{|name, hooks| mhooks[name].update hooks}
  __trait_search_path.map{|ta| ta.__trait_singleton_method_list['writers']}.flatten
#--}}}
end

#__trait_evaluate(*a, &b) ⇒ Object

–}}}



161
162
163
164
165
166
167
168
169
170
171
# File 'lib/traits.rb', line 161

def __trait_evaluate(*a, &b)
#--{{{
  m = "__trait_evaluate__#{ Thread::current.object_id.abs }__#{ rand 42 }__#{ rand 666 }__"
  __trait_singleton_class.module_eval{ define_method m, &b }
  begin
    send m, *a
  ensure
    __trait_singleton_class.module_eval{ remove_method m }
  end
#--}}}
end

#__trait_getopt(opts, key, default = nil) ⇒ Object

–}}}



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/traits.rb', line 35

def __trait_getopt opts, key, default = nil
#--{{{
  return opts.delete(key) if opts.has_key? key

  key = "#{ key }"
  return opts.delete(key) if opts.has_key? key
  key = key.intern
  return opts.delete(key) if opts.has_key? key

  key = "#{ key }s"
  return opts.delete(key) if opts.has_key? key
  key = key.intern
  return opts.delete(key) if opts.has_key? key

  key = "#{ key }es"
  return opts.delete(key) if opts.has_key? key
  key = key.intern
  return opts.delete(key) if opts.has_key? key

  return default
#--}}}
end

#__trait_instance_method_defaultsObject

–}}}



137
138
139
140
141
# File 'lib/traits.rb', line 137

def __trait_instance_method_defaults
#--{{{
    @__trait_instance_method_defaults ||= {}
#--}}}
end

#__trait_instance_method_hooksObject

–}}}



147
148
149
150
151
152
153
# File 'lib/traits.rb', line 147

def __trait_instance_method_hooks
#--{{{
    @__trait_instance_method_hooks ||= 
      #Hash::new{ |h,name| h[name] = {'pre' => nil, 'post' => nil, 'validate' => nil, 'munge' => nil, 'cast' => nil} }
      Hash::new{ |h,name| h[name] = {} }
#--}}}
end

#__trait_instance_method_listObject

–}}}



127
128
129
130
131
# File 'lib/traits.rb', line 127

def __trait_instance_method_list
#--{{{
  @__trait_instance_method_list ||= {'writers' => [], 'readers' => [], }
#--}}}
end

#__trait_search_pathObject

–}}}



29
30
31
32
33
34
# File 'lib/traits.rb', line 29

def __trait_search_path
#--{{{
  #((Class === self and not __trait_singleton?) ? ancestors : [self])
  (__trait_singleton? or not respond_to? 'ancestors') ? [self] : ancestors
#--}}}
end

#__trait_singleton?Boolean

–}}}

Returns:

  • (Boolean)


23
24
25
26
27
28
# File 'lib/traits.rb', line 23

def __trait_singleton?
#--{{{
  @__is_trait_singleton ||= 
    ((Class === self) and (@__is_trait_singleton ||= (not self.ancestors.include?(self))))
#--}}}
end

#__trait_singleton_classObject

–}}}



18
19
20
21
22
# File 'lib/traits.rb', line 18

def __trait_singleton_class
#--{{{
  @__trait_singleton_class ||= class << self;self;end
#--}}}
end

#__trait_singleton_method_defaultsObject

–}}}



142
143
144
145
146
# File 'lib/traits.rb', line 142

def __trait_singleton_method_defaults
#--{{{
    @__trait_singleton_method_defaults ||= {} 
#--}}}
end

#__trait_singleton_method_hooksObject

–}}}



154
155
156
157
158
159
160
# File 'lib/traits.rb', line 154

def __trait_singleton_method_hooks
#--{{{
    @__trait_singleton_method_hooks ||= 
      #Hash::new{ |h,name| h[name] = {'pre' => nil, 'post' => nil, 'validate' => nil, 'munge' => nil, 'cast' => nil} }
      Hash::new{ |h,name| h[name] = {} }
#--}}}
end

#__trait_singleton_method_listObject

–}}}



132
133
134
135
136
# File 'lib/traits.rb', line 132

def __trait_singleton_method_list
#--{{{
  @__trait_singleton_method_list ||= {'writers' => [], 'readers' => [], }
#--}}}
end

#singleton_method_added(*a, &b) ⇒ Object

–{{{



10
11
12
13
14
15
16
17
# File 'lib/traits.rb', line 10

def singleton_method_added(*a, &b)
#--{{{
  ret = super rescue nil
  obj = self
  obj.__trait_singleton_class.__trait_module_eval{ @__trait_singleton_super = obj }
  ret
#--}}}
end