Module: N::PropertyUtils

Defined in:
lib/nitro/markup.rb,
lib/glue/property.rb

Overview

A collection of Property related utility methods.

Class Method Summary collapse

Class Method Details

.add_prop(target, prop) ⇒ Object

Add the property to the target (Class or Module)



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/glue/property.rb', line 120

def self.add_prop(target, prop)
	if idx = target.__props.index(prop)
		# override in case of duplicates. Keep the order of the props.
		target.__props[idx] = prop
	else
		target.__props << prop
	end
	
	# Precompile the property read/write methods

	s, klass = prop.symbol, prop.klass

	if prop.meta[:reader]
		target.module_eval %{
			def #{s}
				return @#{s}
			end
		}
	end
		
	# gmosx: __force_xxx reuses xxx= to allow for easier
	# overrides.

	if prop.meta[:writer]
		target.module_eval %{
			#{prop_setter(prop)}
			
			def __force_#{s}(val)
					self.#{s}=(} + case klass.name
						when Fixnum.name
							"val.to_i()"
						when String.name
							"val.to_s()"
						when Float.name
							"val.to_f()"
						when Time.name
							"Time.parse(val.to_s())"
						when TrueClass.name, FalseClass.name
							"val.to_i() > 0"
						else
							"val"
					end + %{) 
			end
		}
	end
end

.copy_props(src, dest) ⇒ Object

Copy properties from src (Module or Class) to dest.



106
107
108
109
110
111
112
113
114
115
116
# File 'lib/glue/property.rb', line 106

def self.copy_props(src, dest)
	src.__props.each do |p|
		add_prop(dest, p)
	end
	
	# copy the metadata.
	src.__meta.each do |k, val|
		dest.__meta[k] = val.dup
		# val.each { |v| dest.meta(k, v) } if val
	end
end

.enchant(target, force = false) ⇒ Object

Add accessors to the properties to the given target (Module or Class). For simplicity also create the meta accessors.

target

The target class or module – gmosx: Perhaps we ‘ll optimize this in the future. ++



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/glue/property.rb', line 79

def self.enchant(target, force = false)
	unless target.singleton_methods.include?('__props')
		target.module_eval %{  
			@@__meta = N::SafeHash.new
			@@__props = N::SafeArray.new
			
			def self.__props
				@@__props
			end

			def self.__props=(props)
				@@__props = props
			end
			
			def self.__meta
				@@__meta
			end

			def self.__meta=(meta)
				@@__meta = meta
			end
		}
	end
end

.get_prop(klass, sym) ⇒ Object

Get the property metadata for the given symbol.



195
196
197
# File 'lib/glue/property.rb', line 195

def self.get_prop(klass, sym)
	return klass.__props.find { |p| p.symbol == sym }
end

.include_meta_mixins(target) ⇒ Object

Include meta-language mixins



201
202
203
204
205
# File 'lib/glue/property.rb', line 201

def self.include_meta_mixins(target)
	target.module_eval %{ include N::Validation } if defined?(N::Validation)
	# gmosx: TODO, make Og::MetaLanguage equivalent to Validation.
	target.module_eval %{ extend Og::MetaLanguage } if defined?(Og::MetaLanguage)
end

.prop_setter(prop) ⇒ Object

Generates the property setter code. Can be overriden to support extra functionality (example: markup)



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/nitro/markup.rb', line 17

def self.prop_setter(prop)
	s = prop.symbol
	if markup = prop.meta[:markup]
		# if true, set to default Markup
		markup = N::Markup if true == markup

		code = %{
			def #{s}=(val)
		}
		
		if N::Property.type_checking
			code << %{
				unless String == val.class
					raise "Invalid type, expected '#{prop.klass}', is '\#\{val.class\}'."
				end
			}
		end

		code << %{
				@#{s} = #{markup}.expand(val)
			end

			def compact_#{s}
				#{markup}.compact(@#{s})
			end
		}

		return code
	else
		return %{
			def #{s}=(val)
				@#{s} = val
			end
		}
	end
end

.resolve_prop_params(*params) ⇒ Object

Resolves the parameters passed to the propxxx macros to generate the meta, klass and symbols variables. This way the common functionality is factored out.

params

The params to resolve.

one_symbol

If true, only resolves one symbol (used in prop).



216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/glue/property.rb', line 216

def self.resolve_prop_params(*params)
	meta = {}
	klass = Object
	symbols = []

	for param in params.flatten
		if param.is_a?(Class)
			klass = param
		elsif param.is_a?(Symbol)
			symbols << param
		elsif param.is_a?(TrueClass) or param.is_a?(TrueClass) 
			writer = param
		elsif param.is_a?(Hash)
			# the meta hash.
			meta.update(param) { |k, a, b| [a,b].join(' ') }
		else
			raise 'Error when defining property!'
		end
	end

	raise 'No symbols provided!' if symbols.empty?

	return meta, klass, symbols
end