List Info

Thread: Serious discussion on Annotaitons - Part I




Serious discussion on Annotaitons - Part I
user name
2006-10-29 11:37:51
First of all here is the code for the annotations system in
the latest
Facets. If you compare it to the old version you'll see it's
a lot less
complex. Now appearently something doesn't work right in
Nitro with it
but as of yet no one has been able to give me one concrete
error as to
what is going wrong. Off the top of my head I know that some
meta-information methods (like #inheritance) is no longer
there so that
would break things, or if one were trying to jerry things
using
inheritor which is no longer used. But in using it normally
it should
work, I have a bunch of test cases and they all work --so I
really need
to get some concerete idea about what the problem is so I
can fix it.

Thanks,
T.

(P.S. I'm going to follow this up with a discussion of
annotations in
general).

# --- annotations.rb

class Annotations

  def initialize( base )
    base, ann = base, {}
  end

  def [](key)
    key = :self if key == base
    ann[key] ||= Annotation.new(base, key)
  end

  def []=(key, note)
    raise ArgumentError unless Annotation === note
    ann[key] = note
  end

  def ==(other) ann == other.to_h end

  def to_h() ann end

  def key?(key) ann.key?(key) end

  def each(&yld)
    ann.each(&yld)
  end

  def update( other )
    ann.update( other.to_h )
    self
  end
  private :update

  def self
    self[:self]
  end

  def annotated_base() base end

  def method_missing( key, *args, &blk )
    if key?(key)
      self[key] #.heritage
    else
      if base.ancestors.any?{|anc| anc.annotations.key?(key)}
        return self[key].heritage
        #ann[name].heritage
      end
      super
    end
  end

end

#

class Annotation < OpenObject

  def initialize( base, key, orig=nil )
    base = base
    key  = key
    orig = orig || self
    super()
  end

  def original
    orig
  end

  #def class
  #  self[:class]
  #end

  def inspect
    "#<#{object_class.name}(#{base}##{key})
#>"
  end

  def annotation_key
    key
  end

  def heritage( orig=nil )
    ah = {}
    base.ancestors.reverse_each do |anc|
      if anc.annotations.key?(key)
        anc.annotations[key].each { |k,v|
          case v
          when Module
            ah[k] = v
          else
            ah[k] = v.dup rescue v
          end
        }
      end
    end
    a = Annotation.new( base, key, orig
|| orig )
    a.send(:replace, ah)
    a
  end

  def method_missing( sym, *args, &blk )
    type = sym.to_s[-1,1]
    key = sym.to_s.gsub(/[=!?]$/, '').to_sym

    case type
    when '='
      orig[key] = args[0] #, *args, &blk )
    when '!'
      #r = super( key, *args, &blk )
      if key?(key)
        self[key]
      else
        self[key] = heritage(self)[key]
      end
    else
      heritage[sym]
    end
  end

end

class Module

  def annotations
    annotations ||= Annotations.new(self)
  end

  def ann( key=nil, *options )
    return annotations unless key
    return name.collect{|k,v| ann k,*v} if Hash === key
    return annotations[key] if options.empty?
    opt = {}
    opt.update options.pop if Hash === options.last
    opt[:class] = options.pop if Class === options.last
    keys = [key].concat options
    keys.each do |key|
      note = annotations[key]
      #unless options.empty?
      #  (hopt[:tags] ||= []) << options
      #end
      note.send(:update,opt)
    end
    keys
  end

end

module Kernel
  # Any object can be annotated.
  #--
  # Not sure about this.
  #++
  def ann( *args )
    #if singleton_class?
      (class << self; self; end).ann( *args )
    #else
    #  self.class.ann( *args )
    #end
  end
end

_______________________________________________
Nitro-general mailing list
Nitro-generalrubyforge.org
h
ttp://rubyforge.org/mailman/listinfo/nitro-general
[1]

about | contact  Other archives ( Real Estate discussion Medical topics )