openlogic-rdf 0.3.6

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 (80) hide show
  1. data/AUTHORS +3 -0
  2. data/CREDITS +9 -0
  3. data/README +361 -0
  4. data/UNLICENSE +24 -0
  5. data/VERSION +1 -0
  6. data/bin/rdf +18 -0
  7. data/etc/doap.nt +62 -0
  8. data/lib/df.rb +1 -0
  9. data/lib/rdf/cli.rb +200 -0
  10. data/lib/rdf/format.rb +383 -0
  11. data/lib/rdf/mixin/countable.rb +39 -0
  12. data/lib/rdf/mixin/durable.rb +31 -0
  13. data/lib/rdf/mixin/enumerable.rb +637 -0
  14. data/lib/rdf/mixin/indexable.rb +26 -0
  15. data/lib/rdf/mixin/inferable.rb +5 -0
  16. data/lib/rdf/mixin/mutable.rb +191 -0
  17. data/lib/rdf/mixin/queryable.rb +265 -0
  18. data/lib/rdf/mixin/readable.rb +15 -0
  19. data/lib/rdf/mixin/type_check.rb +21 -0
  20. data/lib/rdf/mixin/writable.rb +152 -0
  21. data/lib/rdf/model/graph.rb +263 -0
  22. data/lib/rdf/model/list.rb +731 -0
  23. data/lib/rdf/model/literal/boolean.rb +121 -0
  24. data/lib/rdf/model/literal/date.rb +73 -0
  25. data/lib/rdf/model/literal/datetime.rb +72 -0
  26. data/lib/rdf/model/literal/decimal.rb +86 -0
  27. data/lib/rdf/model/literal/double.rb +189 -0
  28. data/lib/rdf/model/literal/integer.rb +126 -0
  29. data/lib/rdf/model/literal/numeric.rb +184 -0
  30. data/lib/rdf/model/literal/time.rb +87 -0
  31. data/lib/rdf/model/literal/token.rb +47 -0
  32. data/lib/rdf/model/literal/xml.rb +39 -0
  33. data/lib/rdf/model/literal.rb +373 -0
  34. data/lib/rdf/model/node.rb +156 -0
  35. data/lib/rdf/model/resource.rb +28 -0
  36. data/lib/rdf/model/statement.rb +296 -0
  37. data/lib/rdf/model/term.rb +77 -0
  38. data/lib/rdf/model/uri.rb +570 -0
  39. data/lib/rdf/model/value.rb +133 -0
  40. data/lib/rdf/nquads.rb +152 -0
  41. data/lib/rdf/ntriples/format.rb +48 -0
  42. data/lib/rdf/ntriples/reader.rb +239 -0
  43. data/lib/rdf/ntriples/writer.rb +219 -0
  44. data/lib/rdf/ntriples.rb +104 -0
  45. data/lib/rdf/query/pattern.rb +329 -0
  46. data/lib/rdf/query/solution.rb +252 -0
  47. data/lib/rdf/query/solutions.rb +237 -0
  48. data/lib/rdf/query/variable.rb +221 -0
  49. data/lib/rdf/query.rb +404 -0
  50. data/lib/rdf/reader.rb +511 -0
  51. data/lib/rdf/repository.rb +389 -0
  52. data/lib/rdf/transaction.rb +161 -0
  53. data/lib/rdf/util/aliasing.rb +63 -0
  54. data/lib/rdf/util/cache.rb +139 -0
  55. data/lib/rdf/util/file.rb +38 -0
  56. data/lib/rdf/util/uuid.rb +36 -0
  57. data/lib/rdf/util.rb +6 -0
  58. data/lib/rdf/version.rb +19 -0
  59. data/lib/rdf/vocab/cc.rb +18 -0
  60. data/lib/rdf/vocab/cert.rb +13 -0
  61. data/lib/rdf/vocab/dc.rb +63 -0
  62. data/lib/rdf/vocab/dc11.rb +23 -0
  63. data/lib/rdf/vocab/doap.rb +45 -0
  64. data/lib/rdf/vocab/exif.rb +168 -0
  65. data/lib/rdf/vocab/foaf.rb +69 -0
  66. data/lib/rdf/vocab/geo.rb +13 -0
  67. data/lib/rdf/vocab/http.rb +26 -0
  68. data/lib/rdf/vocab/owl.rb +59 -0
  69. data/lib/rdf/vocab/rdfs.rb +17 -0
  70. data/lib/rdf/vocab/rsa.rb +12 -0
  71. data/lib/rdf/vocab/rss.rb +14 -0
  72. data/lib/rdf/vocab/sioc.rb +93 -0
  73. data/lib/rdf/vocab/skos.rb +36 -0
  74. data/lib/rdf/vocab/wot.rb +21 -0
  75. data/lib/rdf/vocab/xhtml.rb +9 -0
  76. data/lib/rdf/vocab/xsd.rb +58 -0
  77. data/lib/rdf/vocab.rb +215 -0
  78. data/lib/rdf/writer.rb +475 -0
  79. data/lib/rdf.rb +192 -0
  80. metadata +173 -0
@@ -0,0 +1,389 @@
1
+ module RDF
2
+ ##
3
+ # An RDF repository.
4
+ #
5
+ # @example Creating a transient in-memory repository
6
+ # repository = RDF::Repository.new
7
+ #
8
+ # @example Checking whether a repository is readable/writable
9
+ # repository.readable?
10
+ # repository.writable?
11
+ #
12
+ # @example Checking whether a repository is persistent or transient
13
+ # repository.persistent?
14
+ # repository.transient?
15
+ #
16
+ # @example Checking whether a repository is empty
17
+ # repository.empty?
18
+ #
19
+ # @example Checking how many statements a repository contains
20
+ # repository.count
21
+ #
22
+ # @example Checking whether a repository contains a specific statement
23
+ # repository.has_statement?(statement)
24
+ #
25
+ # @example Enumerating statements in a repository
26
+ # repository.each_statement { |statement| statement.inspect! }
27
+ #
28
+ # @example Inserting statements into a repository
29
+ # repository.insert(*statements)
30
+ # repository.insert(statement)
31
+ # repository.insert([subject, predicate, object])
32
+ # repository << statement
33
+ # repository << [subject, predicate, object]
34
+ #
35
+ # @example Deleting statements from a repository
36
+ # repository.delete(*statements)
37
+ # repository.delete(statement)
38
+ # repository.delete([subject, predicate, object])
39
+ #
40
+ # @example Deleting all statements from a repository
41
+ # repository.clear!
42
+ #
43
+ class Repository
44
+ include RDF::Countable
45
+ include RDF::Enumerable
46
+ include RDF::Queryable
47
+ include RDF::Mutable
48
+ include RDF::Durable
49
+
50
+ ##
51
+ # Returns the options passed to this repository when it was constructed.
52
+ #
53
+ # @return [Hash{Symbol => Object}]
54
+ attr_reader :options
55
+
56
+ ##
57
+ # Returns the {URI} of this repository.
58
+ #
59
+ # @return [URI]
60
+ attr_reader :uri
61
+ alias_method :url, :uri
62
+
63
+ ##
64
+ # Returns the title of this repository.
65
+ #
66
+ # @return [String]
67
+ attr_reader :title
68
+
69
+ ##
70
+ # Loads one or more RDF files into a new transient in-memory repository.
71
+ #
72
+ # @param [String, Array<String>] filenames
73
+ # @param [Hash{Symbol => Object}] options
74
+ # Options from {RDF::Reader#initialize}, {RDF::Format.for} and {RDF::Repository#initialize}
75
+ # @yield [repository]
76
+ # @yieldparam [Repository]
77
+ # @return [void]
78
+ def self.load(filenames, options = {}, &block)
79
+ self.new(options) do |repository|
80
+ [filenames].flatten.each do |filename|
81
+ repository.load(filename, options)
82
+ end
83
+
84
+ if block_given?
85
+ case block.arity
86
+ when 1 then block.call(repository)
87
+ else repository.instance_eval(&block)
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ ##
94
+ # Initializes this repository instance.
95
+ #
96
+ # @param [Hash{Symbol => Object}] options
97
+ # @option options [URI, #to_s] :uri (nil)
98
+ # @option options [String, #to_s] :title (nil)
99
+ # @yield [repository]
100
+ # @yieldparam [Repository] repository
101
+ def initialize(options = {}, &block)
102
+ @options = options.dup
103
+ @uri = @options.delete(:uri)
104
+ @title = @options.delete(:title)
105
+
106
+ # Provide a default in-memory implementation:
107
+ send(:extend, Implementation) if self.class.equal?(RDF::Repository)
108
+
109
+ if block_given?
110
+ case block.arity
111
+ when 1 then block.call(self)
112
+ else instance_eval(&block)
113
+ end
114
+ end
115
+ end
116
+
117
+ ##
118
+ # Returns a developer-friendly representation of this object.
119
+ #
120
+ # @return [String]
121
+ def inspect
122
+ sprintf("#<%s:%#0x(%s)>", self.class.name, __id__, uri.to_s)
123
+ end
124
+
125
+ ##
126
+ # Outputs a developer-friendly representation of this object to
127
+ # `stderr`.
128
+ #
129
+ # @return [void]
130
+ def inspect!
131
+ each_statement { |statement| statement.inspect! }
132
+ nil
133
+ end
134
+
135
+ ##
136
+ # Executes the given block in a transaction.
137
+ #
138
+ # @example
139
+ # repository.transaction do |tx|
140
+ # tx.insert [RDF::URI("http://rdf.rubyforge.org/"), RDF::DC.title, "RDF.rb"]
141
+ # end
142
+ #
143
+ # @param [RDF::Resource] context
144
+ # @yield [tx]
145
+ # @yieldparam [RDF::Transaction] tx
146
+ # @yieldreturn [void] ignored
147
+ # @return [void] `self`
148
+ # @see RDF::Transaction
149
+ # @since 0.3.0
150
+ def transaction(context = nil, &block)
151
+ tx = begin_transaction(context)
152
+ begin
153
+ case block.arity
154
+ when 1 then block.call(tx)
155
+ else tx.instance_eval(&block)
156
+ end
157
+ rescue => error
158
+ rollback_transaction(tx)
159
+ raise error
160
+ end
161
+ commit_transaction(tx)
162
+ self
163
+ end
164
+ alias_method :transact, :transaction
165
+
166
+ protected
167
+
168
+ ##
169
+ # Begins a new transaction.
170
+ #
171
+ # Subclasses implementing transaction-capable storage adapters may wish
172
+ # to override this method in order to begin a transaction against the
173
+ # underlying storage.
174
+ #
175
+ # @param [RDF::Resource] context
176
+ # @return [RDF::Transaction]
177
+ # @since 0.3.0
178
+ def begin_transaction(context)
179
+ RDF::Transaction.new(:context => context)
180
+ end
181
+
182
+ ##
183
+ # Rolls back the given transaction.
184
+ #
185
+ # Subclasses implementing transaction-capable storage adapters may wish
186
+ # to override this method in order to roll back the given transaction in
187
+ # the underlying storage.
188
+ #
189
+ # @param [RDF::Transaction] tx
190
+ # @return [void] ignored
191
+ # @since 0.3.0
192
+ def rollback_transaction(tx)
193
+ # nothing to do
194
+ end
195
+
196
+ ##
197
+ # Commits the given transaction.
198
+ #
199
+ # Subclasses implementing transaction-capable storage adapters may wish
200
+ # to override this method in order to commit the given transaction to
201
+ # the underlying storage.
202
+ #
203
+ # @param [RDF::Transaction] tx
204
+ # @return [void] ignored
205
+ # @since 0.3.0
206
+ def commit_transaction(tx)
207
+ tx.execute(self)
208
+ end
209
+
210
+ ##
211
+ # @see RDF::Repository
212
+ module Implementation
213
+ DEFAULT_CONTEXT = false
214
+
215
+ ##
216
+ # @private
217
+ def self.extend_object(obj)
218
+ obj.instance_variable_set(:@data, obj.options.delete(:data) || {})
219
+ super
220
+ end
221
+
222
+ ##
223
+ # @private
224
+ # @see RDF::Readable#supports?
225
+ def supports?(feature)
226
+ case feature.to_sym
227
+ when :context then true # statement contexts / named graphs
228
+ when :inference then false # forward-chaining inference
229
+ else false
230
+ end
231
+ end
232
+
233
+ ##
234
+ # @private
235
+ # @see RDF::Durable#durable?
236
+ def durable?
237
+ false
238
+ end
239
+
240
+ ##
241
+ # @private
242
+ # @see RDF::Countable#empty?
243
+ def empty?
244
+ @data.empty?
245
+ end
246
+
247
+ ##
248
+ # @private
249
+ # @see RDF::Countable#count
250
+ def count
251
+ count = 0
252
+ @data.each do |c, ss|
253
+ ss.each do |s, ps|
254
+ ps.each do |p, os|
255
+ count += os.size
256
+ end
257
+ end
258
+ end
259
+ count
260
+ end
261
+
262
+ ##
263
+ # @private
264
+ # @see RDF::Enumerable#has_statement?
265
+ def has_statement?(statement)
266
+ s, p, o, c = statement.to_quad
267
+ c ||= DEFAULT_CONTEXT
268
+ @data.has_key?(c) &&
269
+ @data[c].has_key?(s) &&
270
+ @data[c][s].has_key?(p) &&
271
+ @data[c][s][p].include?(o)
272
+ end
273
+
274
+ ##
275
+ # @private
276
+ # @see RDF::Enumerable#each_statement
277
+ def each_statement(&block)
278
+ if block_given?
279
+ # Note that to iterate in a more consistent fashion despite
280
+ # possible concurrent mutations to `@data`, we use `#dup` to make
281
+ # shallow copies of the nested hashes before beginning the
282
+ # iteration over their keys and values.
283
+ @data.dup.each do |c, ss|
284
+ ss.dup.each do |s, ps|
285
+ ps.dup.each do |p, os|
286
+ os.dup.each do |o|
287
+ block.call(RDF::Statement.new(s, p, o, :context => c.equal?(DEFAULT_CONTEXT) ? nil : c))
288
+ end
289
+ end
290
+ end
291
+ end
292
+ end
293
+ enum_statement
294
+ end
295
+ alias_method :each, :each_statement
296
+
297
+ ##
298
+ # @private
299
+ # @see RDF::Enumerable#has_context?
300
+ def has_context?(value)
301
+ @data.keys.include?(value)
302
+ end
303
+
304
+ ##
305
+ # @private
306
+ # @see RDF::Enumerable#each_context
307
+ def each_context(&block)
308
+ if block_given?
309
+ contexts = @data.keys
310
+ contexts.delete(DEFAULT_CONTEXT)
311
+ contexts.each(&block)
312
+ end
313
+ enum_context
314
+ end
315
+
316
+ protected
317
+
318
+ ##
319
+ # Match elements with eql?, not ==
320
+ # Context of `false` matches default context. Unbound variable matches non-false context
321
+ # @private
322
+ # @see RDF::Queryable#query
323
+ def query_pattern(pattern, &block)
324
+ context = pattern.context
325
+ subject = pattern.subject
326
+ predicate = pattern.predicate
327
+ object = pattern.object
328
+
329
+ cs = @data.has_key?(context) ? {context => @data[context]} : @data.dup
330
+ cs.each do |c, ss|
331
+ next unless context.nil? || context == false && !c || context.eql?(c)
332
+ ss = ss.has_key?(subject) ? {subject => ss[subject]} : ss.dup
333
+ ss.each do |s, ps|
334
+ next unless subject.nil? || subject.eql?(s)
335
+ ps = ps.has_key?(predicate) ? {predicate => ps[predicate]} : ps.dup
336
+ ps.each do |p, os|
337
+ next unless predicate.nil? || predicate.eql?(p)
338
+ os = os.dup # TODO: is this really needed?
339
+ os.each do |o|
340
+ next unless object.nil? || object.eql?(o)
341
+ block.call(RDF::Statement.new(s, p, o, :context => c.equal?(DEFAULT_CONTEXT) ? nil : c))
342
+ end
343
+ end
344
+ end
345
+ end
346
+ end
347
+
348
+ ##
349
+ # @private
350
+ # @see RDF::Mutable#insert
351
+ def insert_statement(statement)
352
+ unless has_statement?(statement)
353
+ s, p, o, c = statement.to_quad
354
+ c ||= DEFAULT_CONTEXT
355
+ @data[c] ||= {}
356
+ @data[c][s] ||= {}
357
+ @data[c][s][p] ||= []
358
+ @data[c][s][p] << o
359
+ end
360
+ end
361
+
362
+ ##
363
+ # @private
364
+ # @see RDF::Mutable#delete
365
+ def delete_statement(statement)
366
+ if has_statement?(statement)
367
+ s, p, o, c = statement.to_quad
368
+ c ||= DEFAULT_CONTEXT
369
+ @data[c][s][p].delete(o)
370
+ @data[c][s].delete(p) if @data[c][s][p].empty?
371
+ @data[c].delete(s) if @data[c][s].empty?
372
+ @data.delete(c) if @data[c].empty?
373
+ end
374
+ end
375
+
376
+ ##
377
+ # @private
378
+ # @see RDF::Mutable#clear
379
+ def clear_statements
380
+ @data.clear
381
+ end
382
+
383
+ protected :query_pattern
384
+ protected :insert_statement
385
+ protected :delete_statement
386
+ protected :clear_statements
387
+ end # Implementation
388
+ end # Repository
389
+ end # RDF
@@ -0,0 +1,161 @@
1
+ module RDF
2
+ ##
3
+ # An RDF transaction.
4
+ #
5
+ # Transactions consist of a sequence of RDF statements to delete from and
6
+ # a sequence of RDF statements to insert into a given named graph.
7
+ #
8
+ # @example Executing a transaction against a repository
9
+ # repository = ...
10
+ # RDF::Transaction.execute(repository) do |tx|
11
+ # subject = RDF::URI("http://example.org/article")
12
+ # tx.delete [subject, RDF::DC.title, "Old title"]
13
+ # tx.insert [subject, RDF::DC.title, "New title"]
14
+ # end
15
+ #
16
+ # @since 0.3.0
17
+ class Transaction
18
+ include RDF::Mutable
19
+
20
+ ##
21
+ # Executes a transaction against the given RDF repository.
22
+ #
23
+ # @param [RDF::Repository] repository
24
+ # @param [Hash{Symbol => Object}] options
25
+ # @yield [tx]
26
+ # @yieldparam [RDF::Transaction] tx
27
+ # @return [void]
28
+ def self.execute(repository, options = {}, &block)
29
+ self.new(&block).execute(repository, options)
30
+ end
31
+
32
+ ##
33
+ # RDF graph to modify when executed.
34
+ #
35
+ # @return [RDF::Resource]
36
+ attr_reader :graph
37
+
38
+ ##
39
+ # RDF statements to delete when executed.
40
+ #
41
+ # @return [RDF::Enumerable]
42
+ attr_reader :deletes
43
+
44
+ ##
45
+ # RDF statements to insert when executed.
46
+ #
47
+ # @return [RDF::Enumerable]
48
+ attr_reader :inserts
49
+
50
+ ##
51
+ # Any additional options for this transaction.
52
+ #
53
+ # @return [Hash{Symbol => Object}]
54
+ attr_reader :options
55
+
56
+ ##
57
+ # Initializes this transaction.
58
+ #
59
+ # @param [Hash{Symbol => Object}] options
60
+ # @option options [RDF::Resource] :graph (nil)
61
+ # @option options [RDF::Enumerable] :insert (RDF::Graph.new)
62
+ # @option options [RDF::Enumerable] :delete (RDF::Graph.new)
63
+ # @yield [tx]
64
+ # @yieldparam [RDF::Transaction] tx
65
+ def initialize(options = {}, &block)
66
+ @options = options.dup
67
+ @graph = @options.delete(:graph) || @options.delete(:context)
68
+ @inserts = @options.delete(:insert) || RDF::Graph.new
69
+ @deletes = @options.delete(:delete) || RDF::Graph.new
70
+ @inserts.extend(RDF::Enumerable) unless @inserts.kind_of?(RDF::Enumerable)
71
+ @deletes.extend(RDF::Enumerable) unless @deletes.kind_of?(RDF::Enumerable)
72
+
73
+ if block_given?
74
+ case block.arity
75
+ when 1 then block.call(self)
76
+ else instance_eval(&block)
77
+ end
78
+ end
79
+ end
80
+
81
+ ##
82
+ # Returns `false` to indicate that this transaction is append-only.
83
+ #
84
+ # Transactions do not support the `RDF::Enumerable` protocol directly.
85
+ # To enumerate the RDF statements to be inserted or deleted, use the
86
+ # {#inserts} and {#deletes} accessors.
87
+ #
88
+ # @return [Boolean]
89
+ # @see RDF::Readable#readable?
90
+ def readable?
91
+ false
92
+ end
93
+
94
+ ##
95
+ # Executes this transaction against the given RDF repository.
96
+ #
97
+ # @param [RDF::Repository] repository
98
+ # @param [Hash{Symbol => Object}] options
99
+ # @return [void]
100
+ def execute(repository, options = {})
101
+ before_execute(repository, options) if respond_to?(:before_execute)
102
+
103
+ deletes.each_statement do |statement|
104
+ statement = statement.dup
105
+ statement.context = graph
106
+ repository.delete(statement)
107
+ end
108
+
109
+ inserts.each_statement do |statement|
110
+ statement = statement.dup
111
+ statement.context = graph
112
+ repository.insert(statement)
113
+ end
114
+
115
+ after_execute(repository, options) if respond_to?(:after_execute)
116
+ self
117
+ end
118
+
119
+ ##
120
+ # Returns a developer-friendly representation of this transaction.
121
+ #
122
+ # @return [String]
123
+ def inspect
124
+ sprintf("#<%s:%#0x(graph: %s, deletes: %d, inserts: %d)>", self.class.name, __id__,
125
+ graph ? graph.to_s : 'nil', deletes.count, inserts.count)
126
+ end
127
+
128
+ ##
129
+ # Outputs a developer-friendly representation of this transaction to
130
+ # `stderr`.
131
+ #
132
+ # @return [void]
133
+ def inspect!
134
+ warn(inspect)
135
+ end
136
+
137
+ ##
138
+ # Appends an RDF statement to the sequence to insert when executed.
139
+ #
140
+ # @param [RDF::Statement] statement
141
+ # @return [void]
142
+ # @see RDF::Writable#insert_statement
143
+ def insert_statement(statement)
144
+ inserts << statement
145
+ end
146
+
147
+ ##
148
+ # Appends an RDF statement to the sequence to delete when executed.
149
+ #
150
+ # @param [RDF::Statement] statement
151
+ # @return [void]
152
+ # @see RDF::Mutable#delete_statement
153
+ def delete_statement(statement)
154
+ deletes << statement
155
+ end
156
+
157
+ undef_method :load, :update, :clear
158
+ protected :insert_statement
159
+ protected :delete_statement
160
+ end # Transaction
161
+ end # RDF
@@ -0,0 +1,63 @@
1
+ module RDF; module Util
2
+ module Aliasing
3
+ ##
4
+ # Helpers for late-bound instance method aliasing.
5
+ #
6
+ # Anything that extends this module will obtain an `alias_method` class
7
+ # method that creates late-bound instance method aliases instead of the
8
+ # default early-bound aliases created by Ruby's `Module#alias_method`.
9
+ #
10
+ # This is useful because RDF.rb mixins typically alias a number of
11
+ # overridable methods. For example, `RDF::Enumerable#count` has the
12
+ # aliases `#size` and `#length`. Normally if implementing classes were
13
+ # to override the default method, the aliased methods would still be
14
+ # bound to the mixin's original reference implementation rather than the
15
+ # new overridden method. Mixing in this module into the implementing
16
+ # class fixes this problem.
17
+ #
18
+ # @example Using late-bound aliasing in a module
19
+ # module MyModule
20
+ # extend RDF::Util::Aliasing::LateBound
21
+ # end
22
+ #
23
+ # @example Using late-bound aliasing in a class
24
+ # class MyClass
25
+ # extend RDF::Util::Aliasing::LateBound
26
+ # end
27
+ #
28
+ # @see http://en.wikipedia.org/wiki/Name_binding
29
+ # @since 0.2.0
30
+ module LateBound
31
+ ##
32
+ # Makes `new_name` a late-bound alias of the method `old_name`.
33
+ #
34
+ # @example Aliasing the `#count` method to `#size` and `#length`
35
+ # alias_method :size, :count
36
+ # alias_method :length, :count
37
+ #
38
+ # @param [Symbol, #to_sym] new_name
39
+ # @param [Symbol, #to_sym] old_name
40
+ # @return [void]
41
+ # @see http://ruby-doc.org/core/classes/Module.html#M001653
42
+ def alias_method(new_name, old_name)
43
+ new_name, old_name = new_name.to_sym, old_name.to_sym
44
+
45
+ class_eval(<<-EOF)
46
+ def #{new_name}(*args, &block)
47
+ #{old_name}(*args, &block)
48
+ end
49
+ EOF
50
+
51
+ # NOTE: the following eval-less (and hence slightly less evil)
52
+ # implementation only works on Ruby 1.8.7+ due to the |&block|
53
+ # syntax that was introduced in 1.9 and then backported to 1.8.7;
54
+ # it is a syntax error in earlier versions of Ruby:
55
+ #self.__send__(:define_method, new_name) do |*args, &block|
56
+ # __send__(old_name, *args, &block)
57
+ #end
58
+
59
+ return self
60
+ end
61
+ end # LateBound
62
+ end # Aliasing
63
+ end; end # RDF::Util