1 | # -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4
|
---|
2 | # $Id: tag.rb 11708 2007-02-12 23:01:19Z shyouhei $
|
---|
3 | #
|
---|
4 | # = yaml/tag.rb: methods for associating a taguri to a class.
|
---|
5 | #
|
---|
6 | # Author:: why the lucky stiff
|
---|
7 | #
|
---|
8 | module YAML
|
---|
9 | # A dictionary of taguris which map to
|
---|
10 | # Ruby classes.
|
---|
11 | @@tagged_classes = {}
|
---|
12 |
|
---|
13 | #
|
---|
14 | # Associates a taguri _tag_ with a Ruby class _cls_. The taguri is used to give types
|
---|
15 | # to classes when loading YAML. Taguris are of the form:
|
---|
16 | #
|
---|
17 | # tag:authorityName,date:specific
|
---|
18 | #
|
---|
19 | # The +authorityName+ is a domain name or email address. The +date+ is the date the type
|
---|
20 | # was issued in YYYY or YYYY-MM or YYYY-MM-DD format. The +specific+ is a name for
|
---|
21 | # the type being added.
|
---|
22 | #
|
---|
23 | # For example, built-in YAML types have 'yaml.org' as the +authorityName+ and '2002' as the
|
---|
24 | # +date+. The +specific+ is simply the name of the type:
|
---|
25 | #
|
---|
26 | # tag:yaml.org,2002:int
|
---|
27 | # tag:yaml.org,2002:float
|
---|
28 | # tag:yaml.org,2002:timestamp
|
---|
29 | #
|
---|
30 | # The domain must be owned by you on the +date+ declared. If you don't own any domains on the
|
---|
31 | # date you declare the type, you can simply use an e-mail address.
|
---|
32 | #
|
---|
33 | # tag:[email protected],2004:notes/personal
|
---|
34 | #
|
---|
35 | def YAML.tag_class( tag, cls )
|
---|
36 | if @@tagged_classes.has_key? tag
|
---|
37 | warn "class #{ @@tagged_classes[tag] } held ownership of the #{ tag } tag"
|
---|
38 | end
|
---|
39 | @@tagged_classes[tag] = cls
|
---|
40 | end
|
---|
41 |
|
---|
42 | # Returns the complete dictionary of taguris, paired with classes. The key for
|
---|
43 | # the dictionary is the full taguri. The value for each key is the class constant
|
---|
44 | # associated to that taguri.
|
---|
45 | #
|
---|
46 | # YAML.tagged_classes["tag:yaml.org,2002:int"] => Integer
|
---|
47 | #
|
---|
48 | def YAML.tagged_classes
|
---|
49 | @@tagged_classes
|
---|
50 | end
|
---|
51 | end
|
---|
52 |
|
---|
53 | class Module
|
---|
54 | # :stopdoc:
|
---|
55 |
|
---|
56 | # Adds a taguri _tag_ to a class, used when dumping or loading the class
|
---|
57 | # in YAML. See YAML::tag_class for detailed information on typing and
|
---|
58 | # taguris.
|
---|
59 | def yaml_as( tag, sc = true )
|
---|
60 | verbose, $VERBOSE = $VERBOSE, nil
|
---|
61 | class_eval <<-"end;", __FILE__, __LINE__+1
|
---|
62 | attr_writer :taguri
|
---|
63 | def taguri
|
---|
64 | if respond_to? :to_yaml_type
|
---|
65 | YAML::tagurize( to_yaml_type[1..-1] )
|
---|
66 | else
|
---|
67 | return @taguri if defined?(@taguri) and @taguri
|
---|
68 | tag = #{ tag.dump }
|
---|
69 | if self.class.yaml_tag_subclasses? and self.class != YAML::tagged_classes[tag]
|
---|
70 | tag = "\#{ tag }:\#{ self.class.yaml_tag_class_name }"
|
---|
71 | end
|
---|
72 | tag
|
---|
73 | end
|
---|
74 | end
|
---|
75 | def self.yaml_tag_subclasses?; #{ sc ? 'true' : 'false' }; end
|
---|
76 | end;
|
---|
77 | YAML::tag_class tag, self
|
---|
78 | ensure
|
---|
79 | $VERBOSE = verbose
|
---|
80 | end
|
---|
81 | # Transforms the subclass name into a name suitable for display
|
---|
82 | # in a subclassed tag.
|
---|
83 | def yaml_tag_class_name
|
---|
84 | self.name
|
---|
85 | end
|
---|
86 | # Transforms the subclass name found in the tag into a Ruby
|
---|
87 | # constant name.
|
---|
88 | def yaml_tag_read_class( name )
|
---|
89 | name
|
---|
90 | end
|
---|
91 | end
|
---|