Imported File#ftype spec from rubyspecs.
[rbx.git] / lib / rbyaml / tag.rb
blob5a69ad2398c17b7a6ba0a54813eaf95116c2db21
1 module RbYAML
2   # A dictionary of taguris which map to
3   # Ruby classes.
4   @@tagged_classes = {}
5   
6   # 
7   # Associates a taguri _tag_ with a Ruby class _cls_.  The taguri is used to give types
8   # to classes when loading YAML.  Taguris are of the form:
9   #
10   #   tag:authorityName,date:specific
11   #
12   # The +authorityName+ is a domain name or email address.  The +date+ is the date the type
13   # was issued in YYYY or YYYY-MM or YYYY-MM-DD format.  The +specific+ is a name for
14   # the type being added.
15   # 
16   # For example, built-in YAML types have 'yaml.org' as the +authorityName+ and '2002' as the
17   # +date+.  The +specific+ is simply the name of the type:
18   #
19   #  tag:yaml.org,2002:int
20   #  tag:yaml.org,2002:float
21   #  tag:yaml.org,2002:timestamp
22   #
23   # The domain must be owned by you on the +date+ declared.  If you don't own any domains on the
24   # date you declare the type, you can simply use an e-mail address.
25   #
26   #  tag:why@ruby-lang.org,2004:notes/personal
27   #
28   def self.tag_class( tag, cls )
29     if @@tagged_classes.has_key? tag
30       warn "class #{ @@tagged_classes[tag] } held ownership of the #{ tag } tag"
31     end
32     @@tagged_classes[tag] = cls
33   end
35   # Returns the complete dictionary of taguris, paired with classes.  The key for
36   # the dictionary is the full taguri.  The value for each key is the class constant
37   # associated to that taguri.
38   #
39   #  YAML.tagged_classes["tag:yaml.org,2002:int"] => Integer
40   #
41   def self.tagged_classes
42     @@tagged_classes
43   end
44 end
46 class Module # :nodoc: all
47   def yaml_as( tag, sc = true )
48     class_eval <<-_WHY, __FILE__, __LINE__+1
49     attr_writer :taguri
50     def taguri
51       return @taguri if defined?(@taguri) and @taguri
52       tag = #{ tag.dump }
53       if self.class.yaml_tag_subclasses? then
54         subclass = RbYAML::tagged_classes[tag]
55         if self.class != subclass then
56           tag = "\#{ tag }:\#{ self.class.yaml_tag_class_name }"
57         end
58       end
59       tag
60     end
61     def self.yaml_tag_subclasses?; #{!!sc} ; end
62     _WHY
63     RbYAML::tag_class tag, self
64   end
65   # Transforms the subclass name into a name suitable for display
66     # in a subclassed tag.
67   def yaml_tag_class_name
68     self.name
69   end
70   # Transforms the subclass name found in the tag into a Ruby
71   # constant name.
72   def yaml_tag_read_class( name )
73     name
74   end
75 end