metaruby 1.0.0.rc3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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