metaruby 1.0.0.rc3 → 1.0.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0f6d60aa23a3e9e790ac1613c65fc2a0b446f0de
4
- data.tar.gz: e22d9104e853727888c91504b5d25dbf29234e9a
3
+ metadata.gz: 209d7c5d2bfb1aef6d4370e9b87d5635f4cbe093
4
+ data.tar.gz: ebbba741e3cb1511ebf7f05a6e4e4d242b23ffda
5
5
  SHA512:
6
- metadata.gz: e59cba378c250b744c75cd654c426cbbd801812df83e45a07fe2ba22ef15a903490d61d039ea67cdfc275e2dbf629739f1507f30ef16aacd79b52f8948be0c3f
7
- data.tar.gz: 58bee189d56019dab2103b3944d3ec24001e044ce16dd76ca3101f9ff097652c44dbdabc6862affeed7f1a522fd7b839c54da0a016236c57447adb1591126de5
6
+ metadata.gz: 6fffccb4135deee4fa523fc09b79a9ab66eb8783ec7de35bc88a29876842909210795adca46afc8514b4ae28de51ed9c4045a0e8f54da06cf8948424629edc2c
7
+ data.tar.gz: 2b832a3185e0b0a4c657979a1b0a86f362541d4cb09364355b40c50d7bbcd86de4fe5356131f36af6d669ea8dd08f7d7faadb5710d303abff23d1ff488d0779c
data/.gitignore CHANGED
@@ -2,3 +2,4 @@
2
2
  coverage/
3
3
  doc/
4
4
  .*.sw?
5
+ pkg/
data/.travis.yml CHANGED
@@ -4,6 +4,8 @@ rvm:
4
4
  - 2.0.0
5
5
  - 2.1.6
6
6
  - 2.2.2
7
+ - 2.3.0
8
+ - jruby-9.0.4.0
7
9
  script:
8
10
  - bundle exec rake
9
11
  - bundle exec rake test
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
- # Metamodelling in the Ruby type system
1
+ [![Build Status](https://travis-ci.org/rock-core/tools-metaruby.svg?branch=master)](https://travis-ci.org/rock-core/tools-metaruby)
2
+ [![Gem Version](https://badge.fury.io/rb/metaruby.svg)](http://badge.fury.io/rb/metaruby)
3
+ [![Documentation](http://b.repl.ca/v1/yard-docs-blue.png)](http://rubydoc.info/gems/metaruby/frames)
2
4
 
3
- * https://gitorious.org/rock-toolchain/metaruby
5
+ # Metamodelling in the Ruby type system
4
6
 
5
7
  MetaRuby is a library that allows to (ab)use the Ruby type system to create
6
8
  reflexive programs: create a specialized modelling API (a.k.a. "a DSL") at the
data/Rakefile CHANGED
@@ -6,6 +6,7 @@ task :default
6
6
  Rake::TestTask.new(:test) do |t|
7
7
  t.libs << "lib"
8
8
  t.libs << "."
9
+ t.ruby_opts << '-w'
9
10
  t.test_files = FileList['test/suite.rb']
10
11
  end
11
12
 
@@ -36,35 +36,6 @@ module MetaRuby
36
36
  # end
37
37
  # end
38
38
  module Attributes
39
- # Internal representation of inherited attributes
40
- class InheritedAttribute < Struct.new(:single_value, :name, :accessor_name, :init)
41
- end
42
-
43
- # The set of inherited attributes defined on this object
44
- # @return [Array<InheritedAttribute>]
45
- attribute(:inherited_attributes) { Array.new }
46
-
47
- # Tests for the existence of an inherited attribute by its name
48
- #
49
- # @param [String] name the attribute name
50
- # @return [Boolean] true if there is an attribute defined with the given
51
- # name
52
- def inherited_attribute_defined?(name)
53
- inherited_attributes.any? { |ih| ih.name == name }
54
- end
55
-
56
- # Returns the inherited attribute definition that matches the given name
57
- #
58
- # @param [String] name the attribute name
59
- # @return [InheritedAttribute] the attribute definition
60
- # @raise [ArgumentError] if no attribute with that name exists
61
- def inherited_attribute_by_name(name)
62
- if attr = inherited_attributes.find { |ih| ih.name == name }
63
- return attr
64
- else raise ArgumentError, "#{self} has no inherited attribute called #{name}"
65
- end
66
- end
67
-
68
39
  def included(mod)
69
40
  mod.extend Attributes
70
41
  end
@@ -288,20 +259,19 @@ module MetaRuby
288
259
  # B.enum_for(:each_mapped, 'name').to_a # => ["B"]
289
260
  # B.enum_for(:each_mapped, 'name', false).to_a # => ["B", "A"]
290
261
  #
291
- def inherited_attribute(name, attribute_name = name, options = Hash.new, &init) # :nodoc:
262
+ def inherited_attribute(name, attribute_name = name, yield_key: true, map: false, enum_with: :each, &init) # :nodoc:
292
263
  # Set up the attribute accessor
293
264
  attribute(attribute_name, &init)
294
265
  class_eval { private "#{attribute_name}=" }
295
266
 
296
267
  promote = method_defined?("promote_#{name}")
297
- options[:enum_with] ||= :each
298
268
 
299
269
  class_eval <<-EOF, __FILE__, __LINE__+1
300
270
  def all_#{name}; each_#{name}.to_a end
301
271
  def self_#{name}; @#{attribute_name} end
302
272
  EOF
303
273
 
304
- if options[:map]
274
+ if map
305
275
  class_eval <<-EOF, __FILE__, __LINE__+1
306
276
  def find_#{name}(key)
307
277
  raise ArgumentError, "nil cannot be used as a key in find_#{name}" if !key
@@ -343,16 +313,16 @@ module MetaRuby
343
313
  EOF
344
314
 
345
315
  if !promote
346
- if options[:map]
347
- class_eval(*Attributes.map_without_promotion(name, attribute_name, options))
316
+ if map
317
+ class_eval(*Attributes.map_without_promotion(name, attribute_name, yield_key: yield_key, enum_with: enum_with))
348
318
  else
349
- class_eval(*Attributes.nomap_without_promotion(name, attribute_name, options))
319
+ class_eval(*Attributes.nomap_without_promotion(name, attribute_name, enum_with: enum_with))
350
320
  end
351
321
  else
352
- if options[:map]
353
- class_eval(*Attributes.map_with_promotion(name, attribute_name, options))
322
+ if map
323
+ class_eval(*Attributes.map_with_promotion(name, attribute_name, yield_key: yield_key, enum_with: enum_with))
354
324
  else
355
- class_eval(*Attributes.nomap_with_promotion(name, attribute_name, options))
325
+ class_eval(*Attributes.nomap_with_promotion(name, attribute_name, enum_with: enum_with))
356
326
  end
357
327
  end
358
328
  end
@@ -361,7 +331,7 @@ module MetaRuby
361
331
  #
362
332
  # Helper class that defines the iteration method for inherited_attribute
363
333
  # when :map is set and there is not promotion method
364
- def self.map_without_promotion(name, attribute_name, options)
334
+ def self.map_without_promotion(name, attribute_name, yield_key: true, enum_with: :each)
365
335
  code, file, line =<<-EOF, __FILE__, __LINE__+1
366
336
  def each_#{name}(key = nil, uniq = true)
367
337
  if !block_given?
@@ -384,7 +354,7 @@ module MetaRuby
384
354
  elsif !uniq
385
355
  for klass in ancestors
386
356
  if klass.instance_variable_defined?(:@#{attribute_name})
387
- klass.#{attribute_name}.#{options[:enum_with]} do |el|
357
+ klass.#{attribute_name}.#{enum_with} do |el|
388
358
  yield(el)
389
359
  end
390
360
  end
@@ -393,10 +363,10 @@ module MetaRuby
393
363
  seen = Set.new
394
364
  for klass in ancestors
395
365
  if klass.instance_variable_defined?(:@#{attribute_name})
396
- klass.#{attribute_name}.#{options[:enum_with]} do |el|
397
- unless seen.include?(el.first)
398
- seen << el.first
399
- yield(el)
366
+ klass.#{attribute_name}.#{enum_with} do |el_key, el|
367
+ if !seen.include?(el_key)
368
+ seen << el_key
369
+ #{if yield_key then 'yield(el_key, el)' else 'yield(el)' end}
400
370
  end
401
371
  end
402
372
  end
@@ -413,7 +383,7 @@ module MetaRuby
413
383
  #
414
384
  # Helper class that defines the iteration method for inherited_attribute
415
385
  # when :map is not set and there is no promotion method
416
- def self.nomap_without_promotion(name, attribute_name, options)
386
+ def self.nomap_without_promotion(name, attribute_name, enum_with: :each)
417
387
  code, file, line =<<-EOF, __FILE__, __LINE__+1
418
388
  def each_#{name}
419
389
  if !block_given?
@@ -426,7 +396,7 @@ module MetaRuby
426
396
  end
427
397
  for klass in ancestors
428
398
  if klass.instance_variable_defined?(:@#{attribute_name})
429
- klass.#{attribute_name}.#{options[:enum_with]} { |el| yield(el) }
399
+ klass.#{attribute_name}.#{enum_with} { |el| yield(el) }
430
400
  end
431
401
  end
432
402
  self
@@ -439,7 +409,7 @@ module MetaRuby
439
409
  #
440
410
  # Helper class that defines the iteration method for inherited_attribute
441
411
  # when :map is set and there is a promotion method
442
- def self.map_with_promotion(name, attribute_name, options)
412
+ def self.map_with_promotion(name, attribute_name, yield_key: true, enum_with: :each)
443
413
  code, file, line =<<-EOF, __FILE__, __LINE__+1
444
414
  def each_#{name}(key = nil, uniq = true)
445
415
  if !block_given?
@@ -469,11 +439,11 @@ module MetaRuby
469
439
  promotions = []
470
440
  for klass in ancestors
471
441
  if klass.instance_variable_defined?(:@#{attribute_name})
472
- klass.#{attribute_name}.#{options[:enum_with]} do |k, v|
442
+ klass.#{attribute_name}.#{enum_with} do |k, v|
473
443
  for p in promotions
474
444
  v = p.promote_#{name}(k, v)
475
445
  end
476
- yield(k, v)
446
+ #{if yield_key then 'yield(k, v)' else 'yield(v)' end}
477
447
  end
478
448
  end
479
449
  promotions.unshift(klass) if klass.respond_to?("promote_#{name}")
@@ -483,13 +453,13 @@ module MetaRuby
483
453
  promotions = []
484
454
  for klass in ancestors
485
455
  if klass.instance_variable_defined?(:@#{attribute_name})
486
- klass.#{attribute_name}.#{options[:enum_with]} do |k, v|
456
+ klass.#{attribute_name}.#{enum_with} do |k, v|
487
457
  unless seen.include?(k)
488
458
  for p in promotions
489
459
  v = p.promote_#{name}(k, v)
490
460
  end
491
461
  seen << k
492
- yield(k, v)
462
+ #{if yield_key then 'yield(k, v)' else 'yield(v)' end}
493
463
  end
494
464
  end
495
465
  end
@@ -506,7 +476,7 @@ module MetaRuby
506
476
  #
507
477
  # Helper class that defines the iteration method for inherited_attribute
508
478
  # when :map is not set and there is a promotion method
509
- def self.nomap_with_promotion(name, attribute_name, options)
479
+ def self.nomap_with_promotion(name, attribute_name, enum_with: :each)
510
480
  code, file, line =<<-EOF, __FILE__, __LINE__+1
511
481
  def each_#{name}
512
482
  if !block_given?
@@ -520,7 +490,7 @@ module MetaRuby
520
490
  promotions = []
521
491
  for klass in ancestors
522
492
  if klass.instance_variable_defined?(:@#{attribute_name})
523
- klass.#{attribute_name}.#{options[:enum_with]} do |value|
493
+ klass.#{attribute_name}.#{enum_with} do |value|
524
494
  for p in promotions
525
495
  value = p.promote_#{name}(value)
526
496
  end
@@ -194,7 +194,7 @@ module MetaRuby
194
194
  each_exception_from(e) do |exception|
195
195
  if !seen.include?(exception)
196
196
  seen << exception
197
- html << render_single_exception(e, "#{id}-#{counter += 1}")
197
+ html << render_single_exception(exception, "#{id}-#{counter += 1}")
198
198
  end
199
199
  end
200
200
  html.join("\n")
@@ -71,7 +71,7 @@ module MetaRuby::GUI
71
71
  @templates = Hash.new
72
72
  @auto_id = 0
73
73
 
74
- if page.kind_of?(Qt::WebPage)
74
+ if defined?(Qt::WebPage) && page.kind_of?(Qt::WebPage)
75
75
  page.link_delegation_policy = Qt::WebPage::DelegateAllLinks
76
76
  Qt::Object.connect(page, SIGNAL('linkClicked(const QUrl&)'), self, SLOT('pageLinkClicked(const QUrl&)'))
77
77
  end
@@ -1,3 +1,4 @@
1
+ require 'kramdown'
1
2
  require 'metaruby/gui/html/button'
2
3
  require 'metaruby/gui/html/page'
3
4
  require 'metaruby/gui/html/collection'
@@ -156,7 +156,7 @@ module MetaRuby
156
156
  end
157
157
 
158
158
  children_modules = children_modules.map do |child_name|
159
- next if !mod.const_defined_here?(child_name)
159
+ next if !mod.const_defined?(child_name, false)
160
160
  # Ruby issues a warning when one tries to access Config
161
161
  # (it has been deprecated in favor of RbConfig). Ignore
162
162
  # it explicitly
@@ -37,17 +37,15 @@ module MetaRuby
37
37
  #
38
38
  # @return [String] the assigned name
39
39
  def name=(name)
40
- # This is dynamically defined. The reason is that there is no way to
41
- # call 'super' to get the default Class#name, so we define our name
42
- # only when it is explicitely assigned
43
- def self.name
44
- if @name then @name
45
- else super
46
- end
47
- end
48
40
  @name = name
49
41
  end
50
42
 
43
+ def name
44
+ if @name then @name
45
+ else super
46
+ end
47
+ end
48
+
51
49
  # The model next in the ancestry chain, or nil if +self+ is root
52
50
  #
53
51
  # @return [Class]
@@ -78,10 +76,10 @@ module MetaRuby
78
76
  Thread.current[FROM_NEW_SUBMODEL_TLS] = true
79
77
  model = self.class.new(self)
80
78
  model.permanent_model = false
79
+ setup_submodel(model, **submodel_options, &block)
81
80
  if name
82
81
  model.name = name
83
82
  end
84
- setup_submodel(model, **submodel_options, &block)
85
83
  model
86
84
  end
87
85
 
@@ -92,6 +90,8 @@ module MetaRuby
92
90
 
93
91
  # Called at the end of the definition of a new submodel
94
92
  def setup_submodel(submodel, register: true, **options, &block)
93
+ submodel.instance_variable_set :@name, nil
94
+
95
95
  if register
96
96
  register_submodel(submodel)
97
97
  end
@@ -106,7 +106,12 @@ module MetaRuby
106
106
  from_new_submodel = Thread.current[FROM_NEW_SUBMODEL_TLS]
107
107
  Thread.current[FROM_NEW_SUBMODEL_TLS] = false
108
108
 
109
- subclass.definition_location = call_stack
109
+ subclass.definition_location =
110
+ if MetaRuby.keep_definition_location?
111
+ call_stack
112
+ else Array.new
113
+ end
114
+ subclass.instance_variable_set :@name, nil
110
115
  super
111
116
  subclass.permanent_model = subclass.accessible_by_name? &&
112
117
  subclass.permanent_definition_context?
@@ -120,6 +125,11 @@ module MetaRuby
120
125
  include model_as_module
121
126
  end
122
127
 
128
+ def self.extend_object(klass)
129
+ super
130
+ klass.instance_variable_set :@name, nil
131
+ end
132
+
123
133
  # Tests whether the given model-as-module is provided by self
124
134
  def provides?(model_as_module)
125
135
  self <= model_as_module
@@ -1,5 +1,3 @@
1
- require 'utilrb/module/const_defined_here_p'
2
-
3
1
  module MetaRuby
4
2
  # Extend in modules that are used as models
5
3
  #
@@ -60,7 +58,7 @@ module MetaRuby
60
58
  def self.create_and_register_submodel(namespace, name, base_model, *args, &block)
61
59
  ModelAsModule.validate_constant_name(name)
62
60
 
63
- if namespace.const_defined_here?(name)
61
+ if namespace.const_defined?(name, false)
64
62
  model = namespace.const_get(name)
65
63
  base_model.setup_submodel(model, *args, &block)
66
64
  else
@@ -96,14 +94,20 @@ module MetaRuby
96
94
  #
97
95
  # @return [String] the assigned name
98
96
  def name=(name)
99
- def self.name
100
- if @name then @name
101
- else super
102
- end
103
- end
104
97
  @name = name
105
98
  end
106
99
 
100
+ def name
101
+ if @name then @name
102
+ else super
103
+ end
104
+ end
105
+
106
+ def self.extend_object(obj)
107
+ obj.instance_variable_set :@name, nil
108
+ super
109
+ end
110
+
107
111
  # Set or get the root model
108
112
  attr_accessor :supermodel
109
113
 
@@ -117,10 +121,15 @@ module MetaRuby
117
121
  def new_submodel(name: nil, type: self.class, **submodel_options, &block)
118
122
  model = type.new
119
123
  model.extend ModelAsModule
120
- if name
121
- model.name = name.dup
122
- end
123
- model.definition_location = call_stack
124
+ model.name =
125
+ if name
126
+ name.dup
127
+ end
128
+ model.definition_location =
129
+ if MetaRuby.keep_definition_location?
130
+ call_stack
131
+ else Array.new
132
+ end
124
133
  setup_submodel(model, submodel_options, &block)
125
134
  model
126
135
  end
@@ -158,15 +167,34 @@ module MetaRuby
158
167
  class_eval(&block)
159
168
  end
160
169
 
170
+ # Tests whether self provides the given model
171
+ #
172
+ # @param [Module] model
173
+ def provides?(model)
174
+ self <= model
175
+ end
176
+
161
177
  # Declares that this model also provides this other given model
162
178
  def provides(model)
163
179
  include model
164
- if model.root?
165
- self.supermodel = model
166
- else
167
- self.supermodel = model.supermodel
180
+
181
+ model_root =
182
+ if model.root? then model
183
+ else model.supermodel
184
+ end
185
+
186
+ if !supermodel
187
+ self.supermodel = model_root
188
+ self.supermodel.register_submodel(self)
189
+ elsif supermodel != model_root
190
+ if model_root.provides?(supermodel)
191
+ self.supermodel = model_root
192
+ elsif !supermodel.provides?(model_root)
193
+ raise ArgumentError, "#{model}'s root is #{model_root} while #{self} is #{supermodel}, which are unrelated"
194
+ end
195
+ self.supermodel.register_submodel(self)
168
196
  end
169
- self.supermodel.register_submodel(self)
197
+
170
198
  self.parent_models.merge(model.parent_models)
171
199
  self.parent_models << model
172
200
  end
@@ -27,16 +27,6 @@ module MetaRuby
27
27
  # @return [Array<WeakRef>] the set of models that are children of this one
28
28
  attribute(:submodels) { Array.new }
29
29
 
30
- # Returns the model that is parent of this one
31
- #
32
- # The default implementation returns superclass if it is extended by
33
- # this Registration module, and nil otherwise
34
- def supermodel
35
- if superclass.respond_to?(:register_submodel)
36
- superclass
37
- end
38
- end
39
-
40
30
  # Returns whether a model is a submodel of self
41
31
  def has_submodel?(model)
42
32
  each_submodel.any? { |m| m == model }
@@ -80,7 +70,11 @@ module MetaRuby
80
70
  # Call to register a model that is a submodel of +self+
81
71
  def register_submodel(klass)
82
72
  if !klass.definition_location
83
- klass.definition_location = call_stack
73
+ klass.definition_location =
74
+ if MetaRuby.keep_definition_location?
75
+ call_stack
76
+ else Array.new
77
+ end
84
78
  end
85
79
 
86
80
  submodels << WeakRef.new(klass)
@@ -1,4 +1,4 @@
1
1
  module MetaRuby
2
2
  # The metaruby library version
3
- VERSION = "1.0.0.rc3"
3
+ VERSION = "1.0.0"
4
4
  end
data/lib/metaruby.rb CHANGED
@@ -1,10 +1,10 @@
1
1
  require 'utilrb/object/attribute'
2
2
  require 'weakref'
3
3
 
4
- require 'metaruby/inherited_attribute'
4
+ require 'metaruby/attributes'
5
5
  require 'metaruby/registration'
6
- require 'metaruby/module'
7
- require 'metaruby/class'
6
+ require 'metaruby/model_as_module'
7
+ require 'metaruby/model_as_class'
8
8
 
9
9
  require 'utilrb/logger'
10
10
 
@@ -20,5 +20,10 @@ module MetaRuby
20
20
  LIB_DIR = File.expand_path('metaruby', File.dirname(__FILE__))
21
21
 
22
22
  extend Logger::Root('MetaRuby', Logger::WARN)
23
+
24
+ class << self
25
+ attr_predicate :keep_definition_location?, true
26
+ end
27
+ self.keep_definition_location = true
23
28
  end
24
29
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metaruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc3
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sylvain Joyeux
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-12-08 00:00:00.000000000 Z
11
+ date: 2016-04-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: utilrb
@@ -101,7 +101,7 @@ files:
101
101
  - Rakefile
102
102
  - bin/.gitattributes
103
103
  - lib/metaruby.rb
104
- - lib/metaruby/class.rb
104
+ - lib/metaruby/attributes.rb
105
105
  - lib/metaruby/dsls.rb
106
106
  - lib/metaruby/dsls/doc.rb
107
107
  - lib/metaruby/dsls/find_through_method_missing.rb
@@ -127,8 +127,8 @@ files:
127
127
  - lib/metaruby/gui/model_selector.rb
128
128
  - lib/metaruby/gui/rendering_manager.rb
129
129
  - lib/metaruby/gui/ruby_constants_item_model.rb
130
- - lib/metaruby/inherited_attribute.rb
131
- - lib/metaruby/module.rb
130
+ - lib/metaruby/model_as_class.rb
131
+ - lib/metaruby/model_as_module.rb
132
132
  - lib/metaruby/registration.rb
133
133
  - lib/metaruby/test.rb
134
134
  - lib/metaruby/version.rb
@@ -150,9 +150,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
150
150
  version: '0'
151
151
  required_rubygems_version: !ruby/object:Gem::Requirement
152
152
  requirements:
153
- - - ">"
153
+ - - ">="
154
154
  - !ruby/object:Gem::Version
155
- version: 1.3.1
155
+ version: '0'
156
156
  requirements: []
157
157
  rubyforge_project:
158
158
  rubygems_version: 2.2.3