ratch 0.2.3 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. data/bin/ratch +60 -47
  2. data/bin/ratch-find +21 -0
  3. data/demo/{README → XR} +0 -0
  4. data/demo/task/stats +0 -2
  5. data/doc/images/clipboard.jpg +0 -0
  6. data/doc/images/clipboard2.png +0 -0
  7. data/doc/images/milles-tn.jpg +0 -0
  8. data/doc/images/mints.png +0 -0
  9. data/doc/images/ratch2.png +0 -0
  10. data/doc/images/ruby-sm.png +0 -0
  11. data/doc/images/silver.gif +0 -0
  12. data/doc/images/toolbox.jpg +0 -0
  13. data/doc/index.html +181 -0
  14. data/doc/notes/original.rb +308 -0
  15. data/doc/rdoc/classes/Array.html +194 -0
  16. data/doc/rdoc/classes/Dir.html +317 -0
  17. data/doc/rdoc/classes/Hash.html +217 -0
  18. data/doc/rdoc/classes/Ratch.html +201 -0
  19. data/doc/rdoc/classes/Ratch/ArgvUtils.html +173 -0
  20. data/doc/rdoc/classes/Ratch/ArgvUtils/Ext.html +285 -0
  21. data/doc/rdoc/classes/Ratch/BatchFile.html +207 -0
  22. data/doc/rdoc/classes/Ratch/BatchManager.html +250 -0
  23. data/doc/rdoc/classes/Ratch/BatchScript.html +127 -0
  24. data/doc/rdoc/classes/Ratch/Batchable.html +373 -0
  25. data/doc/rdoc/classes/Ratch/Build.html +321 -0
  26. data/doc/rdoc/classes/Ratch/BuildManager.html +319 -0
  27. data/doc/rdoc/classes/Ratch/Buildable.html +202 -0
  28. data/doc/rdoc/classes/Ratch/ConfigUtils.html +281 -0
  29. data/doc/rdoc/classes/Ratch/ConsoleUtils.html +189 -0
  30. data/doc/rdoc/classes/Ratch/EmailUtils.html +209 -0
  31. data/doc/rdoc/classes/Ratch/FileUtils.html +674 -0
  32. data/doc/rdoc/classes/Ratch/GeneralOptions.html +430 -0
  33. data/doc/rdoc/classes/Ratch/Task.html +201 -0
  34. data/doc/rdoc/classes/Ratch/TaskManager.html +330 -0
  35. data/doc/rdoc/classes/Ratch/Taskable.html +231 -0
  36. data/doc/rdoc/classes/Ratch/UploadUtils.html +566 -0
  37. data/doc/rdoc/created.rid +1 -0
  38. data/doc/rdoc/files/COPYING.html +1003 -0
  39. data/{demo/doc → doc}/rdoc/files/README.html +36 -5
  40. data/doc/rdoc/files/lib/ratch/argvutils_rb.html +131 -0
  41. data/doc/rdoc/files/lib/ratch/batch_rb.html +155 -0
  42. data/doc/rdoc/files/lib/ratch/batchable_rb.html +131 -0
  43. data/doc/rdoc/files/lib/ratch/batchfile_rb.html +148 -0
  44. data/doc/rdoc/files/lib/ratch/buildable_rb.html +131 -0
  45. data/doc/rdoc/files/lib/ratch/consoleutils_rb.html +131 -0
  46. data/{demo/doc/rdoc/files/lib/foo/foo_rb.html → doc/rdoc/files/lib/ratch/emailutils_rb.html} +35 -41
  47. data/doc/rdoc/files/lib/ratch/facets/multiglob_rb.html +137 -0
  48. data/doc/rdoc/files/lib/ratch/fileutils_rb.html +139 -0
  49. data/doc/rdoc/files/lib/ratch/options_rb.html +131 -0
  50. data/doc/rdoc/files/lib/ratch/taskable_rb.html +131 -0
  51. data/doc/rdoc/files/lib/ratch/uploadutils_rb.html +150 -0
  52. data/doc/rdoc/fr_class_index.html +48 -0
  53. data/doc/rdoc/fr_file_index.html +41 -0
  54. data/doc/rdoc/fr_method_index.html +133 -0
  55. data/{demo/doc → doc}/rdoc/index.html +1 -1
  56. data/{demo/doc → doc}/rdoc/rdoc-style.css +0 -0
  57. data/doc/scrap/flexihead-flip.jpg +0 -0
  58. data/doc/scrap/flexihead.jpg +0 -0
  59. data/doc/scrap/head1.jpg +0 -0
  60. data/doc/scrap/ratch.jpg +0 -0
  61. data/doc/scrap/ratch1.png +0 -0
  62. data/doc/scrap/ratch2.jpg +0 -0
  63. data/doc/scrap/ratch3.png +0 -0
  64. data/doc/scrap/red-ratch.jpg +0 -0
  65. data/doc/scrap/redratchet.jpg +0 -0
  66. data/doc/scrap/ruby-kit/ruby.png +0 -0
  67. data/doc/scrap/scrap.red +256 -0
  68. data/doc/sitemap.yaml +10 -0
  69. data/doc/siteparts/index.red +100 -0
  70. data/doc/siteparts/layout.rhtml +56 -0
  71. data/doc/siteparts/tutorial.red +578 -0
  72. data/doc/style.css +112 -0
  73. data/doc/tutorial.html +722 -0
  74. data/lib/ratch/batch.rb +417 -30
  75. data/lib/ratch/{argvutils.rb → batch/argvutils.rb} +27 -19
  76. data/lib/ratch/batch/build.rb +95 -0
  77. data/lib/ratch/{consoleutils.rb → batch/consoleutils.rb} +0 -0
  78. data/lib/ratch/{emailutils.rb → batch/emailutils.rb} +0 -0
  79. data/lib/ratch/{fileutils.rb → batch/fileutils.rb} +32 -32
  80. data/lib/ratch/{options.rb → batch/options.rb} +0 -0
  81. data/lib/ratch/batch/task.rb +43 -0
  82. data/lib/ratch/manager.rb +34 -0
  83. data/lib/ratch/project/information.rb +257 -0
  84. data/lib/ratch/project/package.rb +82 -0
  85. data/lib/ratch/project/project.rb +531 -0
  86. data/lib/ratch/project/release.rb +112 -0
  87. data/lib/ratch/support/filetest.rb +29 -0
  88. data/lib/ratch/support/setuputils.rb +124 -0
  89. data/lib/ratch/support/signiture.rb +252 -0
  90. data/lib/ratch/support/stage.rb +292 -0
  91. data/lib/ratch/toolset/ruby/pack/gem +85 -0
  92. data/lib/ratch/toolset/ruby/pack/tgz +85 -0
  93. data/lib/ratch/toolset/ruby/{crosstest → test/crosstest} +0 -0
  94. data/lib/ratch/toolset/ruby/{extest → test/extest} +0 -0
  95. data/lib/ratch/toolset/ruby/{isotest → test/isotest} +0 -0
  96. data/lib/ratch/toolset/ruby/{load → test/load} +0 -0
  97. data/lib/ratch/toolset/ruby/{loadtest → test/loadtest} +0 -0
  98. data/lib/ratch/toolset/ruby/{syntax → test/syntax} +0 -0
  99. data/lib/ratch/toolset/ruby/{test → test/test} +0 -0
  100. data/log/{history.rd → history} +6 -0
  101. data/log/{todo.rd → todo} +0 -0
  102. data/meta/MANIFEST +52 -36
  103. data/meta/ROLLRC +2 -0
  104. data/meta/icli.yaml +16 -0
  105. data/meta/{ratch-0.2.3.roll → project.yaml} +1 -7
  106. data/task/release +12 -0
  107. data/{lib/ratch → work/old}/batchfile.rb +0 -0
  108. data/work/project-old.rb +67 -0
  109. data/work/scrap/install +89 -0
  110. data/work/scrap/install.0 +49 -0
  111. data/work/scrap/install.1 +63 -0
  112. data/work/scrap/ludo +25 -0
  113. data/work/scrap/oldtaskable.rb +573 -0
  114. data/work/scrap/ratch.man +39 -0
  115. data/work/scrap/taskable-simple.rb +42 -0
  116. data/work/scrap/taskable.rb +120 -0
  117. metadata +170 -72
  118. data/demo/doc/rdoc/created.rid +0 -1
  119. data/demo/doc/rdoc/fr_class_index.html +0 -26
  120. data/demo/doc/rdoc/fr_file_index.html +0 -28
  121. data/demo/doc/rdoc/fr_method_index.html +0 -27
  122. data/demo/task/config.yaml +0 -2
  123. data/lib/ratch/batchable.rb +0 -169
  124. data/lib/ratch/buildable.rb +0 -182
  125. data/lib/ratch/configutils.rb +0 -132
  126. data/lib/ratch/facets/multiglob.rb +0 -160
  127. data/lib/ratch/taskable.rb +0 -152
  128. data/log/recent.rd +0 -8
  129. data/task/config.yaml +0 -10
@@ -31,28 +31,35 @@ module Ratch
31
31
  module ArgvUtils
32
32
 
33
33
  def commandline
34
- @commandline ||= (ARGV.dup).extend(Ext)
34
+ @commandline ||= ArgVector.new(ARGV)
35
35
  end
36
36
  alias_method :argument_vector, :commandline
37
37
 
38
- module Ext
38
+ #
39
+
40
+ class ArgVector
41
+ attr :argv
42
+
43
+ def initialize(argv)
44
+ @argv = argv.dup
45
+ end
39
46
 
40
47
  def arguments
41
- @arguments ||= select{ |e| e !~ /^-/ && e !~ /=/ }
48
+ @arguments ||= argv.select{ |e| e !~ /^-/ && e !~ /=/ }
42
49
  end
43
50
 
44
51
  def options
45
52
  @options ||= (
46
53
  pms = {}
47
- select{ |e| e =~ /=/ }.each do |e|
48
- pms.store(*split('='))
54
+ argv.select{ |e| /[=]/ =~ e }.each do |e|
55
+ pms.store(*e.split('='))
49
56
  end
50
57
  pms
51
58
  )
52
59
  end
53
60
 
54
61
  def flags
55
- @flags ||= select{ |e| e =~ /^-/ || e !~ /=/ }
62
+ @flags ||= argv.select{ |e| e =~ /^-/ || e !~ /=/ }
56
63
  end
57
64
 
58
65
  # Have specific flag?
@@ -61,6 +68,16 @@ module Ratch
61
68
  flags.include?(flag)
62
69
  end
63
70
 
71
+ #
72
+ def [](x)
73
+ case x
74
+ when Integer
75
+ arguments[x]
76
+ else
77
+ options[x.to_s]
78
+ end
79
+ end
80
+
64
81
  # You can use this if you want to use parameterized
65
82
  # flags w/o the '=', however be aware that the
66
83
  # parameter value will also be listed amoung the
@@ -71,29 +88,20 @@ module Ratch
71
88
  # argv.value('--say') #=> "hello"
72
89
  # argv.arguments #=> ["tom", "hello"]
73
90
  #
91
+
74
92
  def value(flag)
75
- fetch(index(flag)+1)
93
+ argv.fetch(index(flag)+1)
76
94
  end
77
95
 
78
96
  #
79
97
  def value!(flag)
80
98
  @values ||= {}
81
99
  @values[flag] ||= (
82
- delete(index(flag))
83
- delete(index(flag))
100
+ argv.delete(index(flag))
101
+ argv.delete(index(flag))
84
102
  )
85
103
  end
86
104
 
87
- # #
88
- # def [](x)
89
- # case x
90
- # when Integer
91
- # super(x)
92
- # else
93
- # value(x.to_s)
94
- # end
95
- # end
96
-
97
105
  end
98
106
  end
99
107
  end
@@ -0,0 +1,95 @@
1
+ # TITLE:
2
+ #
3
+ # Build
4
+ #
5
+ # COPYING:
6
+ #
7
+ # Copyright (c) 2007 Psi T Corp.
8
+ #
9
+ # This file is part of the ProUtils' Ratch program.
10
+ #
11
+ # Ratch is free software: you can redistribute it and/or modify
12
+ # it under the terms of the GNU General Public License as published by
13
+ # the Free Software Foundation, either version 3 of the License, or
14
+ # (at your option) any later version.
15
+ #
16
+ # Ratch is distributed in the hope that it will be useful,
17
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ # GNU General Public License for more details.
20
+ #
21
+ # You should have received a copy of the GNU General Public License
22
+ # along with Ratch. If not, see <http://www.gnu.org/licenses/>.
23
+
24
+ module Ratch
25
+
26
+ # = Build class
27
+
28
+ class Build
29
+
30
+ attr :match
31
+ attr :needs
32
+ attr :action
33
+
34
+ alias_method :name, :match
35
+
36
+ # Create a new build definition.
37
+
38
+ def initialize(match, *needs, &action)
39
+ @match = match
40
+ @needs = needs
41
+ @action = action
42
+ end
43
+
44
+ # Call this build process for the given path.
45
+
46
+ def call(path)
47
+ if needs.empty?
48
+ dated = true
49
+ elsif File.exist?(path)
50
+ mtime = File.mtime(path)
51
+ dated = needs.find do |file|
52
+ !File.exist?(file) || File.mtime(file) > mtime
53
+ end
54
+ else
55
+ dated = true
56
+ end
57
+ action.call(path) if dated
58
+ end
59
+
60
+ # Does a file match this build definition?
61
+
62
+ def match?(path)
63
+ case match
64
+ when String
65
+ File.fnmatch(match, path)
66
+ when Regexp
67
+ match =~ path
68
+ else
69
+ false # ???
70
+ end
71
+ end
72
+
73
+ # Is this build needed to update/create path?
74
+
75
+ def needed_for?(path)
76
+ return true unless File.exist?(path)
77
+ return true if needed_paths.empty? # TODO: if there are no prereqs then the file is always considered needed. Correct?
78
+ mtimes = needed_paths.collect do |f|
79
+ File.exist?(f) ? File.mtime(f) : Time.now
80
+ end
81
+ mtimes.max > File.mtime(path)
82
+ end
83
+
84
+ # Glob expanded needs.
85
+
86
+ def needed_paths
87
+ #exact = needs.select{|n| File.fnmatch?(n,n)} +
88
+ exact = needs.select{|n| n !~ /[\[*?]/ }
89
+ globs = needs.collect{|n| Dir.glob(n)}.flatten
90
+ (exact + globs).uniq
91
+ end
92
+
93
+ end
94
+
95
+ end
@@ -22,8 +22,8 @@
22
22
  # along with Ratch. If not, see <http://www.gnu.org/licenses/>.
23
23
 
24
24
  require 'fileutils'
25
- require 'ratch/facets/multiglob'
26
-
25
+ require 'facets/dir/multiglob'
26
+ require 'ratch/support/filetest'
27
27
 
28
28
  module Ratch
29
29
 
@@ -170,36 +170,36 @@ module Ratch
170
170
  # task if FileTest.file?(task) && FileTest.executable?(task)
171
171
  # end
172
172
 
173
- # Is a file a command executable?
174
- #
175
- # TODO Probably needs to be fixed for Windows.
176
-
177
- def bin?(path)
178
- is_bin = command_paths.any? do |f|
179
- FileTest.exist?(File.join(f, path))
180
- end
181
- is_bin ? File.basename(path) : false
182
- end
183
-
184
- # This is a support method of #bin?
185
-
186
- def command_paths
187
- @command_paths ||= ENV['PATH'].split(/[:;]/)
188
- end
189
-
190
- # TODO Make more robust.
191
-
192
- UNSAFE = [ '/', '/*', '/**/*' ]
193
-
194
- # Is a path considered reasonably "safe"?
195
-
196
- def safe?(path)
197
- case path
198
- when *UNSAFE
199
- return false
200
- end
201
- true
202
- end
173
+ # # Is a file a command executable?
174
+ # #
175
+ # # TODO Probably needs to be fixed for Windows.
176
+ #
177
+ # def bin?(path)
178
+ # is_bin = command_paths.any? do |f|
179
+ # FileTest.exist?(File.join(f, path))
180
+ # end
181
+ # is_bin ? File.basename(path) : false
182
+ # end
183
+ #
184
+ # # This is a support method of #bin?
185
+ #
186
+ # def command_paths
187
+ # @command_paths ||= ENV['PATH'].split(/[:;]/)
188
+ # end
189
+ #
190
+ # # TODO Make more robust.
191
+ #
192
+ # UNSAFE = [ '/', '/*', '/**/*' ]
193
+ #
194
+ # # Is a path considered reasonably "safe"?
195
+ #
196
+ # def safe?(path)
197
+ # case path
198
+ # when *UNSAFE
199
+ # return false
200
+ # end
201
+ # true
202
+ # end
203
203
 
204
204
  end
205
205
  end
@@ -0,0 +1,43 @@
1
+ # TITLE:
2
+ #
3
+ # Task
4
+ #
5
+ # COPYING:
6
+ #
7
+ # Copyright (c) 2007 Psi T Corp.
8
+ #
9
+ # This file is part of the ProUtils' Ratch program.
10
+ #
11
+ # Ratch is free software: you can redistribute it and/or modify
12
+ # it under the terms of the GNU General Public License as published by
13
+ # the Free Software Foundation, either version 3 of the License, or
14
+ # (at your option) any later version.
15
+ #
16
+ # Ratch is distributed in the hope that it will be useful,
17
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ # GNU General Public License for more details.
20
+ #
21
+ # You should have received a copy of the GNU General Public License
22
+ # along with Ratch. If not, see <http://www.gnu.org/licenses/>.
23
+
24
+ module Ratch
25
+
26
+ # Task is a very simple store for the defined
27
+ # actions and it's prerequisites.
28
+
29
+ class Task
30
+ attr_reader :name, :needs, :action
31
+
32
+ def initialize(name, *needs, &action)
33
+ @name = name.to_s
34
+ @needs = needs
35
+ @action = action
36
+ end
37
+
38
+ def call
39
+ @action.call if @action
40
+ end
41
+ end
42
+
43
+ end
@@ -0,0 +1,34 @@
1
+
2
+ module Ratch
3
+
4
+ class Manager
5
+
6
+ def toolset_directory
7
+ File.join(File.dirname(__FILE__), 'toolset')
8
+ end
9
+
10
+ #
11
+
12
+ def toolset
13
+ files = []
14
+ Dir.chdir(toolset_directory) do
15
+ files = Dir.glob('**/*')
16
+ end
17
+ files
18
+ end
19
+
20
+ #
21
+
22
+ def tool?(fname)
23
+ file = File.join(toolset_directory, fname)
24
+ if File.exist?(file)
25
+ file
26
+ else
27
+ false
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+
@@ -0,0 +1,257 @@
1
+ # = TITLE:
2
+ #
3
+ # Information
4
+ #
5
+ # = COPYING:
6
+ #
7
+ # Copyright (c) 2007 Psi T Corp.
8
+ #
9
+ # This file is part of the ProUtils' Ratch program.
10
+ #
11
+ # Ratch is free software: you can redistribute it and/or modify
12
+ # it under the terms of the GNU General Public License as published by
13
+ # the Free Software Foundation, either version 3 of the License, or
14
+ # (at your option) any later version.
15
+ #
16
+ # Ratch is distributed in the hope that it will be useful,
17
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ # GNU General Public License for more details.
20
+ #
21
+ # You should have received a copy of the GNU General Public License
22
+ # along with Ratch. If not, see <http://www.gnu.org/licenses/>.
23
+
24
+ require 'facets/hash/rekey'
25
+
26
+
27
+ module Ratch
28
+
29
+ # Validation Error
30
+ class ValidationError < Exception
31
+ end
32
+
33
+ #
34
+
35
+ class Information
36
+
37
+ class << self
38
+
39
+ def instance_attributes
40
+ @attributes ||= []
41
+ end
42
+
43
+ # Define an attribute.
44
+
45
+ def attr_accessor(name, *aliases, &blk)
46
+ instance_attributes << name.to_s
47
+ instance_attributes.uniq!
48
+ if blk
49
+ define_method(name, &blk)
50
+ attr_writer(name)
51
+ else
52
+ super(name)
53
+ end
54
+ aliases.each{ |aliaz| alias_accessor(aliaz, name) }
55
+ end
56
+
57
+ # Define an attribute alias.
58
+
59
+ def alias_accessor(aliaz, name)
60
+ alias_method aliaz, name
61
+ alias_method "#{aliaz}=", "#{name}="
62
+ end
63
+
64
+ def validation
65
+ @validation ||= []
66
+ end
67
+
68
+ def validate(message, &block)
69
+ validation << [message, block]
70
+ end
71
+
72
+ # Does this class provide open access?
73
+ #
74
+ #def open_access?
75
+ # false
76
+ #end
77
+
78
+ end
79
+
80
+
81
+ def instance_data
82
+ @instance_data ||= {}
83
+ end
84
+
85
+ # List attributes. (Needed?)
86
+
87
+ def attributes
88
+ self.class.instance_attributes
89
+ end
90
+
91
+
92
+ # Initialize
93
+ ####################
94
+
95
+ def initialize(data={})
96
+ update(data)
97
+ end
98
+
99
+ def update(data)
100
+ instance_data.update(data.rekey(:to_s))
101
+
102
+ data.each do |k,v|
103
+ send("#{k}=", v) rescue nil
104
+ end
105
+
106
+ # TODO Could add yield(self) via:
107
+ #yld.to_h.each do |k,v|
108
+ # send( "#{k}=", v ) rescue nil
109
+ #end
110
+ end
111
+
112
+
113
+ # Access
114
+ ####################
115
+
116
+ # Fetch attribute value, but return nil if it doesn't exist.
117
+ #--
118
+ # TODO Use in method missing instead?
119
+ #++
120
+
121
+ def [](name)
122
+ begin
123
+ h = send(name)
124
+ rescue NoMethodError
125
+ h = nil
126
+ end
127
+ end
128
+
129
+ # Gathers a group of info hash entries into a merged hash.
130
+ # The +names+ are taken in most to least significant order.
131
+ #
132
+ # gather(:package)
133
+ #
134
+ # TODO Change name of this method to something better?
135
+
136
+ def gather( *names )
137
+ result = names.inject({}) do |hash,name|
138
+ attributes.each do |n|
139
+ if n.to_s =~ /^#{name}_(.*?)$/
140
+ hash[$1] = self[n.to_s] if self[n.to_s]
141
+ end
142
+ end
143
+ hash
144
+ end
145
+ result
146
+ end
147
+
148
+ # Collects a group of info entries into a hash.
149
+ # Arguments are a list of info entry names and/or
150
+ # a hash or new name to info entry name.
151
+ #
152
+ # select(:name, :version, :date => :released)
153
+ #
154
+ # This is used to collect info to pass to tools.
155
+
156
+ def select( *args )
157
+ maps = (Hash === args.last ? args.pop : {})
158
+ h = {}
159
+ args.each{ |k| h[k.to_s] = self[k] }
160
+ maps.each{ |k, i| h[k.to_s] = self[i] }
161
+ h
162
+ end
163
+
164
+
165
+ # Validation
166
+ ######################
167
+
168
+ #
169
+ def valid?
170
+ begin
171
+ validate
172
+ return true
173
+ rescue ValidationError
174
+ return false
175
+ end
176
+ end
177
+
178
+ #
179
+ def validate
180
+ self.class.validation.each do |message, block|
181
+ raise(ValidationError, message) unless instance_eval(&block)
182
+ end
183
+ end
184
+
185
+ alias_method :assert_valid, :validate
186
+
187
+
188
+ # Conversion
189
+ #################
190
+
191
+ # Order of attributes for yaml conversion.
192
+
193
+ def to_yaml_properties
194
+ attributes.collect{ |a| "@#{a}" }
195
+ end
196
+
197
+ # Use YAML format.
198
+
199
+ def to_yaml( opts={} )
200
+ require 'yaml'
201
+ super
202
+ end
203
+
204
+ # For yaml conversion, no tag.
205
+
206
+ def taguri; nil; end
207
+
208
+ # Convert to hash.
209
+
210
+ def to_hash
211
+ attributes.inject({}) do |h, a|
212
+ v = self[a.to_s] #send(a)
213
+ h[a] = v unless v.nil?
214
+ h
215
+ end
216
+ end
217
+ alias_method :to_h, :to_hash
218
+
219
+ # Use generic XML format.
220
+
221
+ def to_xml( opts={} )
222
+ raise "not yet implemented"
223
+ end
224
+
225
+ # # Use XOXO microformat.
226
+ #
227
+ # def to_xoxo( opts={} )
228
+ # begin
229
+ # require 'blow/xoxo' # EXTERNAL DEPENDENCY!
230
+ # rescue LoadError
231
+ # puts 'Blow (http://blow.rubyforge.org) is required to use XOXO format'
232
+ # end
233
+ # XOXO.dump(self.to_hash, opts)
234
+ # end
235
+
236
+
237
+ # Arbitrary information
238
+ ############################
239
+
240
+ # # TODO Perhaps not define this at all if open_access? is false.
241
+ #
242
+ # def method_missing( s, *a, &b )
243
+ # super unless self.class.open_access?
244
+ # s = s.to_s
245
+ # if s[-1,1] == '='
246
+ # (class << self; self; end).class_eval do
247
+ # attr_accessor s.chomp('=')
248
+ # end
249
+ # send(s,*a,&b)
250
+ # else
251
+ # nil #super
252
+ # end
253
+ # end
254
+
255
+ end
256
+
257
+ end