om 1.4.2 → 1.4.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,19 +2,32 @@ h1. Common Patterns You'll Use with OM
2
2
 
3
3
  h2. Common Terminology Patterns
4
4
 
5
- h4. element value
6
-
7
- We want an OM term to be assigned so its value is the value of an element.
8
-
9
- Given this xml:
5
+ Let's say we have xml like this:
10
6
 
11
7
  <pre>
12
- <outer>
13
- <element>my value</element>
14
- </outer>
8
+ <outer outerId="hypatia:outer" type="outer type">
9
+ <elementA>valA</elementA>
10
+ <elementB>valB1</elementB>
11
+ <elementB animal="vole">valB2<elementC>
12
+ <elementC type="c type" animal="seagull">valC<elementC>
13
+ <resource type="ead" id="coll.ead" objectId="hypatia:ead_file_asset_fixture">
14
+ <file id="my_ead.xml" format="XML" mimetype="text/xml" size="47570">
15
+ <checksum type="md5">123</checksum>
16
+ <checksum type="sha1">456</checksum>
17
+ </file>
18
+ </resource>
19
+ <resource type="image" id="image" objectId="hypatia:coll_img_file_asset_fixture">
20
+ <file id="my_image.jpg" format="JPG" mimetype="image/jpeg" size="302080">
21
+ <checksum type="md5">789</checksum>
22
+ <checksum type="sha1">666</checksum>
23
+ </file>
24
+ </resource>
25
+ </outer>
15
26
  </pre>
16
27
 
17
- we want to have an OM term named "element" with "my value" as the value.
28
+ h4. element value
29
+
30
+ We want an OM term for the value of an element.
18
31
 
19
32
  In the Datastream Model:
20
33
 
@@ -23,111 +36,307 @@ In the Datastream Model:
23
36
  class ExampleXMLDS < ActiveFedora::NokogiriDatastream
24
37
  # OM (Opinionated Metadata) terminology mapping
25
38
  set_terminology do |t|
26
- t.root(:path => "outer", :xmlns => '')
27
- t.element
39
+ t.root(:path => "outer", :xmlns => '', :namespace_prefix => nil)
40
+ t.elementA
41
+ t.elB(:path => "elementB", :namespace_prefix => nil)
42
+ t.elC(:path => "elementC", :namespace_prefix => nil)
28
43
  end
29
- end # class
44
+ end
30
45
  </pre>
31
46
 
32
- Q: What if we don't want the OM term to be named "element," but "giraffe"?
47
+ This results in :elementA having a value of "valA" and :elB having two values of "valB1" and "valB2", and :elC having a value of "valC"
48
+
49
+ h4. element value given a specific attribute value
50
+
51
+ We want an OM term for the value of an element, but only if the element has a specific attribute value.
33
52
 
34
- A:
53
+ In the Datastream Model:
35
54
 
36
55
  <pre>
56
+ # defines the expected OM terminology for example xml
37
57
  class ExampleXMLDS < ActiveFedora::NokogiriDatastream
58
+ # OM (Opinionated Metadata) terminology mapping
38
59
  set_terminology do |t|
39
60
  t.root(:path => "outer", :xmlns => '')
40
- t.giraffe(:path => "element")
61
+ t.elementC(:attributes=>{:animal=>"seagull"}, :namespace_prefix => nil)
62
+ t.here(:path=>"resource", :attributes=>{:type=>"ead"}, :namespace_prefix => nil)
63
+ t.there(:path=>"resource", :attributes=>{:type=>"nowhere"}, :namespace_prefix => nil)
41
64
  end
42
- end # class
65
+ end
43
66
  </pre>
44
67
 
45
- h4. element value given a specific attribute value
68
+ This results in :elementC having a value of "valC" and :here having a value of "123 456", and :there having a value of nil (or is it ""?)
46
69
 
47
- We want an OM term to be assigned to an element's value, but only when the element has a specific attribute value.
70
+ h4. element value given absence of a specific attribute
48
71
 
49
- Given this xml:
72
+ We want an OM term for an element's value, but only if the element does not have a specific attribute.
50
73
 
51
- <pre>
52
- </outer>
53
- <element my_attr="attr value">element value</element>
54
- </outer>
74
+ <pre>
75
+ # defines the expected OM terminology for example xml
76
+ class ExampleXMLDS < ActiveFedora::NokogiriDatastream
77
+ # OM (Opinionated Metadata) terminology mapping
78
+ set_terminology do |t|
79
+ t.root(:path => "outer", :xmlns => '', :namespace_prefix => nil)
80
+ t.elementB(:attributes=>{:animal=>:none}, :namespace_prefix => nil)
81
+ t.no_attrib(:path => "elementB", :attributes=>{:animal=>:none}, :namespace_prefix => nil)
82
+ end
83
+ end
55
84
  </pre>
56
85
 
57
- we want to have an OM term named "element" with "element value" as the value.
86
+ This results in both :elementB and :no_attib having the single value "valB1"
58
87
 
59
- In the Datastream Model:
88
+
89
+ h4. attribute value
90
+
91
+ We want an OM term for an attribute value
60
92
 
61
93
  <pre>
62
94
  # defines the expected OM terminology for example xml
63
95
  class ExampleXMLDS < ActiveFedora::NokogiriDatastream
64
96
  # OM (Opinionated Metadata) terminology mapping
65
97
  set_terminology do |t|
66
- t.root(:path => "outer", :xmlns => '')
67
- t.element(:attributes=>{:my_attr=>"attr value"})
98
+ t.root(:path => "outer", :xmlns => '', :namespace_prefix => nil)
99
+ t.elementB {
100
+ t.my_attr(:path => {:attribute=>"animal"}, :namespace_prefix => nil)
101
+ }
102
+ t.alternate(:path => "elementB/@animal", :namespace_prefix => nil)
103
+ t.another(:proxy=>[:elementB, :my_attr_])
104
+ t.animal_attrib(:path => {:attribute=>"animal"}, :namespace_prefix => nil)
68
105
  end
69
- end # class
106
+ end
70
107
  </pre>
71
108
 
72
- Q: What if we don't want the OM term to be named "element," but "gazelle"?
109
+ This results in :my_attr, :alternate and :another all having the single value of "vole", and :animal_attrib having the values "vole" and "seagull"
110
+
73
111
 
74
- A:
112
+ h4. an example with :proxy and :ref
75
113
 
76
114
  <pre>
115
+ # defines the expected OM terminology for example xml
77
116
  class ExampleXMLDS < ActiveFedora::NokogiriDatastream
117
+ # OM (Opinionated Metadata) terminology mapping
78
118
  set_terminology do |t|
79
- t.root(:path => "outer", :xmlns => '')
80
- t.gazelle(:path => "element", :attributes=>{:my_attr=>"attr value"})
119
+ t.root(:path => "outer", :xmlns => '', :namespace_prefix => nil)
120
+
121
+ t.resource(:namespace_prefix => nil) {
122
+ t.fedora_pid(:path=>{:attribute=>"objectId"}, :namespace_prefix => nil)
123
+ t.file(:ref=>[:file], :namespace_prefix => nil, :namespace_prefix => nil)
124
+ }
125
+ t.file(:namespace_prefix => nil) {
126
+ t.ds_label(:path=>{:attribute=>"id"}, :namespace_prefix => nil)
127
+ t.size(:path=>{:attribute=>"size"}, :namespace_prefix => nil)
128
+ t.md5(:path=>"checksum", :attributes=>{:type=>"md5"}, :namespace_prefix => nil)
129
+ t.sha1(:path=>"checksum", :attributes=>{:type=>"sha1"}, :namespace_prefix => nil)
130
+ }
131
+ # really want ead where the type is ead and the file format is XML and the file mimetype is text/xml (and the file id is (?coll_ead.xml ... can be whatever the label of the DS is in the FileAsset object))
132
+ t.ead(:ref=>:resource, :attributes=>{:type=>"ead"})
133
+ t.image(:ref=>:resource, :attributes=>{:type=>"image"})
134
+
135
+ t.ead_fedora_pid(:proxy=>[:ead, :fedora_pid])
136
+ t.ead_ds_label(:proxy=>[:ead, :file, :ds_label])
137
+ t.ead_size(:proxy=>[:ead, :file, :size])
138
+ t.ead_md5(:proxy=>[:ead, :file, :md5])
139
+ t.ead_sha1(:proxy=>[:ead, :file, :sha1])
140
+
141
+ t.image_fedora_pid(:proxy=>[:image, :fedora_pid])
142
+ t.image_ds_label(:proxy=>[:image, :file, :ds_label])
143
+ t.image_size(:proxy=>[:image, :file, :size])
144
+ t.image_md5(:proxy=>[:image, :file, :md5])
145
+ t.image_sha1(:proxy=>[:image, :file, :sha1])
81
146
  end
82
147
  end
83
148
  </pre>
84
149
 
85
- h4. attribute value
150
+ This results in
151
+ :ead_fedora_pid has value "hypatia:ead_file_asset_fixture"
152
+ :ead_ds_label has value "my_ead.xml"
153
+ :ead_size has value "47570"
154
+ :ead_md5 has value"123"
155
+ :ead_sha1 has value "456"
86
156
 
87
- We want an OM term to be assigned to an element's attribute value.
157
+ :image_fedora_pid has value "hypatia:coll_img_file_asset_fixture"
158
+ :image_ds_label has value "my_image.jpg"
159
+ :image_size has value "302080"
160
+ :image_md5 has value "789"
161
+ :image_sha1 has value "666"
88
162
 
89
- Given this xml:
163
+
164
+ h4. xpath-y stuff, also using :ref and :proxy and namespaces
165
+
166
+ Let's say we have xml like this:
90
167
 
91
168
  <pre>
92
- </outer>
93
- <element my_attr="attr value">element value</element>
94
- </outer>
169
+ <contentMetadata>
170
+ <resource type="file" id="BU3A5" objectId="val2">
171
+ <file id="BURCH1" format="BINARY">
172
+ <location>content</location>
173
+ </file>
174
+ <file id="BURCH1.html" format="HTML">
175
+ <location>html</location>
176
+ </file>
177
+ </resource>
178
+ </contentMetadata>
95
179
  </pre>
96
180
 
97
- we want to have an OM term named "my_attr" with "attr value" as the value.
181
+ We want an OM term corresponding to the <file> element based on the value of the <location> element. That is, we want to have a :content term when the value of <location> is "content" and an :html term when the value of <location> is "html".
98
182
 
99
183
  In the Datastream Model:
100
184
 
101
- FIXME: is this correct? (Naomi wonders 2011-06-22)
102
-
103
185
  <pre>
104
186
  # defines the expected OM terminology for example xml
105
187
  class ExampleXMLDS < ActiveFedora::NokogiriDatastream
106
188
  # OM (Opinionated Metadata) terminology mapping
107
- set_terminology do |t|
108
- t.root(:path => "outer", :xmlns => '')
109
- t.element {
110
- t.my_attr(:path => {:attribute=>"my_attr"})
111
- }
112
- end
113
- end # class
189
+ t.root(:path=>"contentMetadata", :xmlns => '', :namespace_prefix => nil)
190
+
191
+ t.resource(:namespace_prefix => nil) {
192
+ t.file(:ref=>[:file], :namespace_prefix => nil)
193
+ }
194
+
195
+ t.file(:namespace_prefix => nil) {
196
+ t.location(:path=>"location", :namespace_prefix => nil)
197
+ t.filename(:path=>{:attribute=>"id"}, :namespace_prefix => nil)
198
+ t.format(:path=>{:attribute=>"format"}, :namespace_prefix => nil)
199
+ }
200
+ t.content(:ref=>:file, :path=>'resource/file[location="content"]', :namespace_prefix => nil)
201
+ t.html(:ref=>:file, :path=>'resource/file[location="derivative_html"]', :namespace_prefix => nil)
202
+
203
+ t.content_location(:proxy=>[:content, :location])
204
+ t.content_filename(:proxy=>[:content, :filename])
205
+ t.content_format(:proxy=>[:content, :format])
206
+
207
+ t.html_location(:proxy=>[:html, :location])
208
+ t.html_filename(:proxy=>[:html, :filename])
209
+ t.html_format(:proxy=>[:html, :format])
210
+ end
114
211
  </pre>
115
212
 
116
- Q: What if we don't want the OM term to be named "my_attr," but "hippo"?
213
+ Another example from Molly Pickral of UVa:
214
+
215
+ We want to access just the author and the advisor from the XML below. The two <name> elements must be distinguished by their <roleTerm> value, a grandchild of the <name> element.
216
+ We want an :author term with value "Mary Pickral", and an :advisor term with value "David Jones".
117
217
 
118
- A:
218
+ <pre>
219
+ <mods xmlns="http://www.loc.gov/mods/v3"
220
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.3"
221
+ xsi:schemaLocation="http://www.loc.gov/mods/v3
222
+ http://www.loc.gov/standards/mods/v3/mods-3-3.xsd">
223
+ <name type="personal">
224
+ <namePart type="given">Mary</namePart>
225
+ <namePart type="family">Pickral</namePart>
226
+ <affiliation>University of Virginia</affiliation>
227
+ <namePart>mpc3c</namePart>
228
+ <affiliation>University of Virginia Library</affiliation>
229
+ <role>
230
+ <roleTerm authority="marcrelator" type="code">aut</roleTerm>
231
+ <roleTerm authority="marcrelator" type="text">author</roleTerm>
232
+ </role>
233
+ </name>
234
+ <name type="personal">
235
+ <namePart>der5y</namePart>
236
+ <namePart type="given">David</namePart>
237
+ <namePart type="family">Jones</namePart>
238
+ <affiliation>University of Virginia</affiliation>
239
+ <affiliation>Architectural History Dept.</affiliation>
240
+ <role>
241
+ <roleTerm authority="marcrelator" type="code">ths</roleTerm>
242
+ <roleTerm authority="marcrelator" type="text">advisor</roleTerm>
243
+ </role>
244
+ </name>
245
+ </mods>
246
+ </pre>
247
+
248
+ In the Datastream Model:
119
249
 
120
250
  <pre>
121
- class ExampleXMLDS < ActiveFedora::NokogiriDatastream
251
+ # defines the expected OM terminology for mods thesis example xml
252
+ class ModsThesis < ActiveFedora::NokogiriDatastream
122
253
  set_terminology do |t|
123
- t.root(:path => "outer", :xmlns => '')
124
- t.element {
125
- t.hippo(:path => {:attribute=>"my_attr"})
254
+ t.root(:path=>"mods", :xmlns=>"http://www.loc.gov/mods/v3"))
255
+ t.person(:path=>"name", :namespace_prefix => nil) {
256
+ t.given(:path=>"namePart", attribtues=>{:type=>"given"})
257
+ t.family(:path=>"namePart", attribtues=>{:type=>"family"})
258
+ t.role(:namespace_prefix => nil) {
259
+ t.text(:path=>"roleTerm", :attributes=>{:type=>"text"})
260
+ t.code(:path=>"roleTerm", :attributes=>{:type=>"code"})
261
+ }
126
262
  }
127
- end
263
+ t.author(:ref=>:person, :path=>'name[./role/roleTerm="aut"]')
264
+ t.advisor(:ref=>:person, :path=>'name[./role/roleTerm="ths"]')
265
+
266
+ t.author_given(:proxy=>[:author, :given])
267
+ t.author_family(:proxy=>[:author, :family])
268
+ t.advisor_given(:proxy=>[:advisor, :given])
269
+ t.advisor_family(:proxy=>[:advisor, :family])
270
+ end
128
271
  end
129
272
  </pre>
130
273
 
274
+ This isn't quite what the doctor ordered, but :author_given and :author_family can be used to get the author name; similarly for advisor.
275
+
276
+
277
+
278
+ And a variant on the previous example using namespace prefixes.
279
+
280
+ We want to access just the creator and the repository from the XML below. The two <name> elements must be distinguished by their <roleTerm> value, a grandchild of the <name> element.
281
+ We want a :creator term with value "David Small", and a :repository term with value "Graphic Novel Repository".
282
+
283
+ Our xml:
284
+
285
+ <pre>
286
+ <mods:mods xmlns:mods="http://www.loc.gov/mods/v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="3.3" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-3.xsd">
287
+
288
+ <mods:name type="personal">
289
+ <mods:namePart>David Small</mods:namePart>
290
+ <mods:role>
291
+ <mods:roleTerm authority="marcrelator" type="text">creator</mods:roleTerm>
292
+ </mods:role>
293
+ </mods:name>
294
+ <mods:name type="corporate">
295
+ <mods:namePart>Graphic Novel Repository</mods:namePart>
296
+ <mods:role>
297
+ <mods:roleTerm authority="local" type="text">repository</mods:roleTerm>
298
+ </mods:role>
299
+ </mods:name>
300
+ </mods:mods>
301
+ </pre>
302
+
303
+ In the Datastream model:
304
+
305
+ <pre>
306
+ # defines the expected OM terminology for mods name example xml
307
+ class ModsName < ActiveFedora::NokogiriDatastream
308
+ t.root(:path=>"mods", :xmlns=>"http://www.loc.gov/mods/v3", :schema=>"http://www.loc.gov/standards/mods/v3/mods-3-3.xsd", :namespace_prefix => "mods")
309
+
310
+ t.name_ {
311
+ t.name_part(:path=>"namePart")
312
+ t.family_name(:path=>"namePart", :attributes=>{:type=>"family"})
313
+ t.given_name(:path=>"namePart", :attributes=>{:type=>"given"}, :label=>"first name")
314
+ t.terms_of_address(:path=>"namePart", :attributes=>{:type=>"termsOfAddress"})
315
+ t.role(:ref=>[:role])
316
+ }
317
+ t.role {
318
+ t.role_term_text(:path=>"roleTerm", :attributes=>{:type=>"text"})
319
+ }
320
+
321
+ t.person_full(:ref=>:name, :attributes=>{:type=>"personal"})
322
+ t.person(:proxy=>[:person_full, :name_part])
323
+ t.creator(:ref=>:person, :path=>'name[mods:role/mods:roleTerm="creator"]', :xmlns=>"http://www.loc.gov/mods/v3", :namespace_prefix => "mods")
324
+
325
+ t.corporate_full(:ref=>:name, :attributes=>{:type=>"corporate"})
326
+ t.corporate(:proxy=>[:corporate_full, :name_part])
327
+ t.repository(:ref=>:corporate, :path=>'name[mods:role/mods:roleTerm="repository"]', :xmlns=>"http://www.loc.gov/mods/v3", :namespace_prefix => "mods")
328
+ end
329
+ </pre>
330
+
331
+ This terminology not only gives the :creator and :repository values as desired, but also has :person and :corporate terms for more generic <name> xml. The :person_full and :corporate_full values include the value of the <roleTerm> field, which is undesirable for display, if not the index.
332
+
333
+
334
+ h3. Arguments that can be used in the terminology
335
+
336
+ e.g. :path, :default_content_path, :namespace_prefix ...
337
+
338
+ ok if this is a link to the rdoc that describes ALL of these with
339
+
131
340
 
132
341
  h3. Reserved method names (ie. id_, root_)
133
342
 
data/lib/om/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Om
2
- VERSION = "1.4.2"
2
+ VERSION = "1.4.3"
3
3
  end
@@ -46,12 +46,25 @@ module OM::XML::Document
46
46
  end
47
47
 
48
48
  def method_missing(name, *args)
49
- term = self.class.terminology.retrieve_term(name)
50
- if (term)
51
- OM::XML::DynamicNode.new(name, args.first, self, term)
49
+ if matches = /([^=]*)=$/.match(name.to_s)
50
+ modified_name = matches[1].to_sym
51
+ term = self.class.terminology.retrieve_term(modified_name)
52
+ if (term)
53
+ node = OM::XML::DynamicNode.new(modified_name, nil, self, term)
54
+ node.val=args
55
+ else
56
+ super
57
+ end
52
58
  else
53
- super
59
+ term = self.class.terminology.retrieve_term(name)
60
+ if (term)
61
+ OM::XML::DynamicNode.new(name, args.first, self, term)
62
+ else
63
+ super
64
+ end
54
65
  end
66
+
67
+
55
68
  end
56
69
 
57
70
 
@@ -73,6 +86,8 @@ module OM::XML::Document
73
86
  # @example
74
87
  # find_by_terms( [:person, 1, :first_name] )
75
88
  # Currently, indexes must be integers.
89
+ # @example Pass in your own xpath query if you don't want to bother with Term pointers but do want OM to handle namespaces for you.
90
+ # find_by_terms('//oxns:name[@type="personal"][contains(oxns:role, "donor")]')
76
91
  def find_by_terms(*term_pointer)
77
92
  xpath = self.class.terminology.xpath_with_indexes(*term_pointer)
78
93
  find_by_xpath(xpath) unless xpath.nil?
@@ -2,27 +2,29 @@ module OM
2
2
  module XML
3
3
  #
4
4
  # Provides a natural syntax for using OM Terminologies to access values from xml Documents
5
+ #
6
+ # *Note*: All of these examples assume that @article is an instance of OM::Samples::ModsArticle. Look at that file to see the Terminology.
5
7
  #
6
8
  # @example Return an array of the value(s) "start page" node(s) from the second issue node within the first journal node
7
9
  # # Using DynamicNode syntax:
8
10
  # @article.journal(0).issue(1).pages.start
9
11
  # # Other ways to perform this query:
10
12
  # @article.find_by_terms({:journal => 0}, {:issue => 1}, :pages, :start)
11
- # @article.xpath("//oxns:relatedItem[@type=\"host\"]/oxns:part[2]/extent[@unit="pages"]")
13
+ # @article.ng_xml.xpath("//oxns:relatedItem[@type=\"host\"]/oxns:part[2]/extent[@unit="pages"]", {"oxns"=>"http://www.loc.gov/mods/v3"})
12
14
  #
13
15
  # @example Return an NodeSet of the _first titles_ of all journal nodes
14
16
  # # Using DynamicNode syntax:
15
17
  # @article.journal.title(1)
16
18
  # # Other ways to perform this query:
17
19
  # @article.find_by_terms(:journal, {:title => 1})
18
- # @article.xpath("//oxns:relatedItem[@type=\"host\"]/oxns:titleInfo/oxns:title[1]")
20
+ # @article.ng_xml.xpath("//oxns:relatedItem[@type=\"host\"]/oxns:titleInfo/oxns:title[1]", {"oxns"=>"http://www.loc.gov/mods/v3"})
19
21
  #
20
22
  # @example Find all of the titles from all journals & return the first title Node from that NodeSet
21
23
  # # Using DynamicNode syntax:
22
24
  # @article.journal.title[1]
23
25
  # # Other ways to perform this query:
24
26
  # @article.find_by_terms(:journal, :title)[1]
25
- # @article.xpath("//oxns:relatedItem[@type=\"host\"]/oxns:titleInfo/oxns:title")[1]
27
+ # @article.ng_xml.xpath("//oxns:relatedItem[@type=\"host\"]/oxns:titleInfo/oxns:title", {"oxns"=>"http://www.loc.gov/mods/v3"})[1]
26
28
  #
27
29
  class DynamicNode
28
30
  attr_accessor :key, :index, :parent, :addressed_node, :term
@@ -73,7 +75,9 @@ module OM
73
75
  @document.term_value_update(xpath, y.to_i, z)
74
76
  end
75
77
  end
76
- @document.dirty = true
78
+ if @document.respond_to?(:dirty=)
79
+ @document.dirty = true
80
+ end
77
81
  end
78
82
 
79
83
  def sanitize_new_values(new_values)
@@ -17,6 +17,11 @@ describe "OM::XML::DynamicNode" do
17
17
  expected_values.each {|v| result.should include(v)}
18
18
  end
19
19
 
20
+ it "should be able to set first level elements" do
21
+ @article.abstract = "My Abstract"
22
+ @article.abstract.should == ["My Abstract"]
23
+ end
24
+
20
25
  it "should find elements two deep" do
21
26
  #TODO reimplement so that method_missing with name is only called once. Create a new method for name.
22
27
  @article.name.name_content.val.should == ["Describes a person"]
@@ -66,7 +71,8 @@ describe "OM::XML::DynamicNode" do
66
71
  end
67
72
  end
68
73
 
69
- it "should append nodes at the specified index if possible" do
74
+ it "should append nodes at the specified index if possible, setting dirty to true if the object responds to dirty" do
75
+ @article.stubs(:respond_to?).with(:dirty=).returns(true)
70
76
  @article.expects(:dirty=).with(true).twice
71
77
  @article.journal.title_info = ["all", "for", "the"]
72
78
  @article.journal.title_info(3, 'glory')
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: om
3
3
  version: !ruby/object:Gem::Version
4
- hash: 3
4
+ hash: 1
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 4
9
- - 2
10
- version: 1.4.2
9
+ - 3
10
+ version: 1.4.3
11
11
  platform: ruby
12
12
  authors:
13
13
  - Matt Zumwalt
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2011-09-21 00:00:00 -05:00
18
+ date: 2011-10-19 00:00:00 -05:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency