356: def self.forced_hash(caesars_meth, &b)
357: STDERR.puts "forced_hash: #{caesars_meth}" if Caesars.debug?
358: Caesars.add_known_symbol(self, caesars_meth)
359: module_eval %Q{
360: def #{caesars_meth}(*caesars_names,&b)
361: this_meth = :'#{caesars_meth}'
362:
363: add_known_symbol(this_meth)
364: if Caesars.forced_ignore?(this_meth)
365: STDERR.puts "Forced ignore: \#{this_meth}" if Caesars.debug?
366: return
367: end
368:
369: if @caesars_properties.has_key?(this_meth) && caesars_names.empty? && b.nil?
370: return @caesars_properties[this_meth]
371: end
372:
373: return nil if caesars_names.empty? && b.nil?
374: return method_missing(this_meth, *caesars_names, &b) if caesars_names.empty?
375:
376: # Take the first argument in the list provided to "caesars_meth"
377: caesars_name = caesars_names.shift
378:
379: prev = @caesars_pointer
380: @caesars_pointer[this_meth] ||= Caesars::Hash.new
381:
382: hash = Caesars::Hash.new
383: if @caesars_pointer[this_meth].has_key?(caesars_name)
384: STDERR.puts "duplicate key ignored: \#{caesars_name}"
385: return
386: end
387:
388: # The pointer is pointing to the hash that contains "this_meth".
389: # We wan't to make it point to the this_meth hash so when we call
390: # the block, we'll create new entries in there.
391: @caesars_pointer = hash
392:
393: if Caesars.chilled?(this_meth)
394: # We're done processing this_meth so we want to return the pointer
395: # to the level above.
396: @caesars_pointer = prev
397: @caesars_pointer[this_meth][caesars_name] = b
398: else
399: if b
400: # Since the pointer is pointing to the this_meth hash, all keys
401: # created in the block we be placed inside.
402: b.call
403: end
404: # We're done processing this_meth so we want to return the pointer
405: # to the level above.
406: @caesars_pointer = prev
407: @caesars_pointer[this_meth][caesars_name] = hash
408: end
409:
410: # All other arguments provided to "caesars_meth"
411: # will reference the value for the first argument.
412: caesars_names.each do |name|
413: @caesars_pointer[this_meth][name] = @caesars_pointer[this_meth][caesars_name]
414: end
415:
416: @caesars_pointer = prev # Make sure we're back up one level
417: end
418: }
419: nil
420: end