Class: Ostructer::OsOpenStruct

Inherits:
OsBase show all
Includes:
Comparable
Defined in:
lib/ostructer.rb

Instance Attribute Summary

Attributes inherited from OsBase

#field, #logger, #parent

Instance Method Summary collapse

Methods inherited from OsBase

#full_dot_path

Constructor Details

#initialize(hash_in, logger) ⇒ OsOpenStruct

Returns a new instance of OsOpenStruct.



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/ostructer.rb', line 182

def initialize( hash_in, logger )
  @parent = nil
  @field  = "[!unknown_hash]"

  @logger = logger
  @hash = {}
 
  ## fix: can we change the hash-in-place?? don't create a new one
  
  # todo: add hook for normalize keys  (downcase first letter, strip packages, etc.)    
  hash_in.each do |key,value|
    # downcase first letter (e.g. Address to address)
    key = key[0...1].downcase + key[1..-1]

    @hash[ key ] = value  
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(mn, *a) ⇒ Object



239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
# File 'lib/ostructer.rb', line 239

def method_missing(mn,*a)
 
  mn = mn.to_s
   
  ## convenience property for boolean check
  if mn[-1].chr == "?" 
    mn = mn[0..-2]  # cut of trailing ?      
    if @hash.has_key?(mn)               
      value = @hash.fetch( mn ).fetch( 'text' )
      
      logger.debug "OsOpenStruct - boolean feld '#{mn}' with value '#{value}' returns #{value=='1'}"
              
      return value == "1"  # return
    else
      logger.warn "OsOpenStruct - boolean feld '#{mn}' nicht gefunden in Hash using path '#{full_dot_path}'; returning OsOpenStructNil"
      OsOpenStructNil.new( self, mn+"?", logger )  # return
    end        
  else       
   if @hash.has_key?(mn)
     @hash[mn]
   else
     logger.warn "OsOpenStruct - feld '#{mn}' nicht gefunden in Hash using path '#{full_dot_path}'; returning OsOpenStructNil"
     ## pp self
     OsOpenStructNil.new( self, mn, logger )
   end
  end
end

Instance Method Details

#<=>(other) ⇒ Object



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/ostructer.rb', line 222

def <=>(other)
  
  ## fix: check if struct has short-cut value (e.g. text); short-cut value might not exist
  ## fix/todo: add bool
  
  if other.is_a? Numeric
    logger.debug "OsOpenStruct <=> Numeric:  #{self.to_i} <=> #{other}"
    self.to_i <=> other      
  elsif other.is_a? String
    logger.debug "OsOpenStruct <=> String:  #{self.to_s} <=> #{other}"
    self.to_s <=> other
  else
    logger.debug "OsOpenStruct - no <=> defined for type #{other.class}" 
    nil           
  end    
end

#fetch(key, default = nil) ⇒ Object



216
217
218
# File 'lib/ostructer.rb', line 216

def fetch( key, default = nil )
  @hash.fetch( key, default)
end

#has_key?(key) ⇒ Boolean

Returns:

  • (Boolean)


211
212
213
214
# File 'lib/ostructer.rb', line 211

def has_key?( key )
  # NOTE: use has_key? instead of nil? to avoid warnings in log that are expected if fields are missing
  @hash.has_key?( key.to_s )
end

#to_boolObject



292
293
294
295
296
# File 'lib/ostructer.rb', line 292

def to_bool
  ## todo: how to handle no value exists? return false or nil?
  # puts "[DEBUG] calling MyOpenStruct#to_bool"
  internal_value == 'true'
end

#to_dateObject



287
288
289
290
# File 'lib/ostructer.rb', line 287

def to_date
  logger.debug "calling MyOpenStruct#to_date"
  internal_value     # format to date required for sqlite
end

#to_iObject



281
282
283
284
285
# File 'lib/ostructer.rb', line 281

def to_i
  # puts "[DEBUG] calling OsOpenStruct#to_i"
  value = internal_value
  value.nil? ? nil : value.to_i
end

#to_openstruct_pass2Object

link up: set parent and field



200
201
202
203
204
205
206
207
208
209
# File 'lib/ostructer.rb', line 200

def to_openstruct_pass2   # link up: set parent and field    
  @hash.each do |key,value|
    if value.is_a?( OsOpenStruct ) || value.is_a?( OsArray ) || value.is_a?( OsValue )
      value.field  = key.to_s
      value.parent = self
    end
    value.to_openstruct_pass2
  end    
  # logger.debug "after MyOpenStruct#to_openstruct_pass2  parent=#{parent.nil? ? 'nil' : parent.object_id}, field=#{field}" 
end

#to_sObject



275
276
277
278
279
# File 'lib/ostructer.rb', line 275

def to_s
  # puts "[DEBUG] calling OsOpenStruct#to_s"
  value = internal_value
  value.nil? ? nil : value.to_s
end

#to_xmlObject



268
269
270
271
272
273
# File 'lib/ostructer.rb', line 268

def to_xml
  logger.debug "calling OsOpenStruct#to_xml"
  ## todo: check if CGI module is included
  ## todo: use another unescape method for xml entities??
  CGI.unescapeHTML( internal_value )    
end