auto_attr_init 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2aff008f5f68ce853e809db91a3be15f4616dd4e
4
+ data.tar.gz: c6a56fc95e7089d1e604eb05c084ac2f343f11df
5
+ SHA512:
6
+ metadata.gz: b4edca0530af404b454a6d7c0f74faecd2556e90ad207a48e7a56ef88ac7a5e3670775581a24675ba93dc8bda490e657ab5e186c93c41e555d8e7551b1865170
7
+ data.tar.gz: 028c09f6142746b50a9dfc45f995104198220ae4b57fdbb468faf2c4d8d36672c42b4a7ed6b6a93cc7fea4df3b6cdea056d3f5993b060d9c40fa37e7f0b629c2
@@ -0,0 +1,11 @@
1
+ root = true
2
+
3
+ [*]
4
+ end_of_line = lf
5
+ charset = utf-8
6
+ insert_final_newline = true
7
+ trim_trailing_whitespace = true
8
+
9
+ [*.rb]
10
+ indent_style = space
11
+ indent_size = 2
@@ -0,0 +1,20 @@
1
+ .bundle/
2
+ vendor/
3
+ *.swp
4
+ *.swo
5
+ *.gem
6
+ *.rbc
7
+ .config
8
+ .yardoc
9
+ Gemfile.lock
10
+ InstalledFiles
11
+ _yardoc
12
+ coverage
13
+ doc/
14
+ lib/bundler/man
15
+ pkg
16
+ rdoc
17
+ spec/reports
18
+ test/tmp
19
+ test/version_tmp
20
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,49 @@
1
+ <pre>LICENSE: Public Domain
2
+ AUTHOR: ne_Sachirou &lt;utakata.c4se@gmail.com&gt;
3
+ DATE: 2013-09-23</pre>
4
+
5
+ AutoAttrInit
6
+ ============
7
+
8
+ Dart and CoffeeScript like "automatic field initialization" in Ruby.
9
+
10
+ Dart has automatic field initialization.
11
+
12
+ ```dart
13
+ class Point {
14
+ num x, y;
15
+ Point(this.x, this.y);
16
+ }
17
+ ```
18
+
19
+ CoffeeScript has a same function.
20
+
21
+ ```coffeescript
22
+ class Point
23
+ constructor: (@x, @y) ->
24
+ ```
25
+
26
+ With this gem, you can do like this.
27
+
28
+ ```ruby
29
+ class Point
30
+ def initialize x, y; end
31
+ attr_reader :x, :y
32
+ auto_attr_init
33
+ end
34
+ ```
35
+
36
+ Or like this.
37
+
38
+ ```ruby
39
+ class Point
40
+ def initialize @x, @y; end
41
+ attr_reader :x, :y
42
+ end
43
+ ```
44
+
45
+ _cf._ [Idiomatic Dart | Dart: Structured web apps](https://www.dartlang.org/articles/idiomatic-dart/#automatic-field-initialization) Dart's "automatic field initialization".
46
+
47
+ _cf._ [CoffeeScript Classes, Inheritance, and Super](http://jashkenas.github.io/coffee-script/#classes) CoffeeScript has same function.
48
+
49
+ _cf._ [Dart風のautomatic field initializationをRubyで - c4se記:さっちゃんですよ☆](http://c4se.hatenablog.com/entry/2013/09/23/075129) My blog entry.
@@ -0,0 +1,13 @@
1
+ # coding=utf-8
2
+
3
+ require 'bundler/gem_tasks'
4
+
5
+ desc 'Run tests and show the results.'
6
+ task :test do
7
+ require './lib/auto_attr_init.rb'
8
+ require 'test/unit'
9
+ require './test/helper.rb'
10
+ Test::Unit::AutoRunner.run true
11
+ end
12
+
13
+ task :default
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'auto_attr_init/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'auto_attr_init'
8
+ spec.version = AutoAttrInit::VERSION
9
+ spec.authors = ['ne_Sachirou']
10
+ spec.email = ['utakata.c4se@gmail.com']
11
+ spec.description = %q{Auto attribute initialization.}
12
+ spec.summary = %q{Dart and CoffeeScript like "automatic field initialization" in Ruby.}
13
+ spec.homepage = 'https://github.com/ne-sachirou/AutoAttrInit.rb'
14
+ spec.license = 'Public Domain'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.required_ruby_version = '>= 2.0.0'
22
+ spec.add_dependency 'aspectr'
23
+ spec.add_dependency 'sorcerer'
24
+ spec.add_development_dependency 'bundler', '~> 1.3'
25
+ spec.add_development_dependency 'rake'
26
+ spec.add_development_dependency 'test-unit'
27
+ end
@@ -0,0 +1,3 @@
1
+ # coding=utf-8
2
+
3
+ require "#{__dir__}/auto_attr_init/main.rb"
@@ -0,0 +1,93 @@
1
+ # coding=utf-8
2
+
3
+ using AutoAttrInit::Refinments
4
+
5
+ module AutoAttrInit
6
+ class AssignParams
7
+ # @param object [Object]
8
+ def initialize object
9
+ @object = object
10
+ end
11
+
12
+ # @param args [Array]
13
+ # @param params [Array] [param type, param name, default value | nil][]
14
+ # @return [Hash] { param name => value }
15
+ def assign args, params
16
+ param_args = {}
17
+ key_params, params =
18
+ *params.partition{|param| [:key, :keyrest].include? param[0] }
19
+ unless key_params.empty?
20
+ key_args = args.last.is_a?(Hash) ? args.pop : {}
21
+ param_args = param_args.merge assign_key_params(key_args, key_params)
22
+ end
23
+ if params.any?{|param| param[0] == :rest }
24
+ param_args = param_args.merge assign_rest_params(args, params)
25
+ else
26
+ param_args = param_args.merge assign_req_params(args, params)
27
+ end
28
+ param_args
29
+ end
30
+
31
+ private
32
+ # @param args [Array] value[]
33
+ # @param param [Array] [:req|:opt, param name, default value|nil][]
34
+ # @return [Hash] { param name => value }
35
+ def assign_rest_params args, params
36
+ param_args = {}
37
+ rest_index = params.find_index{|param| param[0] == :rest }
38
+ param_args =
39
+ param_args.merge assign_req_params(
40
+ args[0 .. (rest_index - 1)],
41
+ params[0 .. (rest_index - 1)])
42
+ param_args =
43
+ param_args.merge assign_req_params(
44
+ args[(params.length - args.length) .. -1],
45
+ params[(rest_index + 1) .. -1])
46
+ param_args[params[rest_index][1]] =
47
+ args[rest_index .. (args.length - params.length + 1)]
48
+ param_args
49
+ end
50
+
51
+ # req paramとopt paramのみ存在すると仮定して、paramsをassignする。
52
+ # @param args [Array] value[]
53
+ # @param param [Array] [:req|:opt, param name, default value|nil][]
54
+ # @return [Hash] { param name => value }
55
+ def assign_req_params args, params
56
+ param_args = {}
57
+ params.each_with_index do |param, i|
58
+ type, name, value = *param
59
+ param_args[name] =
60
+ case type
61
+ when :req
62
+ args[i]
63
+ when :opt
64
+ args[i] || @object.instance_eval(value)
65
+ end
66
+ end
67
+ param_args
68
+ end
69
+
70
+ # @param key_args [Hash] { param name => value }
71
+ # @param params [Array] [:key|:keyrest, param name, default value|nil][]
72
+ # @return [Hash] { param name => value }
73
+ def assign_key_params key_args, params
74
+ param_args = {}
75
+ params.select{|param| param[0] == :key }.
76
+ each do |param|
77
+ type, name, value = *param
78
+ param_args[name] =
79
+ key_args.has_key?(name) ?
80
+ key_args[name] :
81
+ @object.instance_eval(value)
82
+ end
83
+ if keyrest_param = params.find{|param| param[0] == :keyrest }
84
+ keyrest_arg = {}
85
+ key_args.each do |name, value|
86
+ keyrest_arg[name] = value unless param_args.has_key?(name)
87
+ end
88
+ param_args[keyrest_param[1]] = keyrest_arg
89
+ end
90
+ param_args
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,35 @@
1
+ # coding=utf-8
2
+
3
+ module AutoAttrInit
4
+ module AutoAi
5
+ # @params names [String[]]
6
+ def auto_attr_init *names
7
+ aspect = AutoAiAspect.new self, names
8
+ aspect.wrap self, :pre_initialize, nil, :initialize
9
+ end
10
+ end
11
+
12
+ # RubyistたちのDRY症候群との戦い
13
+ # http://melborne.github.io/2013/09/27/auto-attr-set-in-ruby/
14
+ module AutoAiAutoSetter
15
+ @@auto_attr_init_finished = false
16
+
17
+ def new *args, &block
18
+ unless @@auto_attr_init_finished
19
+ names = self.instance_method(:initialize).parameters.
20
+ collect{|param| param[1] }.
21
+ select{|name| name.to_s =~ /^@/ }
22
+ unless names.empty?
23
+ auto_attr_init *names
24
+ @@auto_attr_init_finished = true
25
+ end
26
+ end
27
+ super *args, &block
28
+ end
29
+ end
30
+ end
31
+
32
+ class Class
33
+ include AutoAttrInit::AutoAi
34
+ prepend AutoAttrInit::AutoAiAutoSetter
35
+ end
@@ -0,0 +1,22 @@
1
+ # coding=utf-8
2
+
3
+ module AutoAttrInit
4
+ # initialize methodのaspect。
5
+ # See AutoAttrInit::AutoAi
6
+ class AutoAiAspect < AspectR::Aspect
7
+ # @params klass [Class]
8
+ # @params names [Symbol[]]
9
+ def initialize klass, names = []
10
+ @params = DetectParams.new(klass).detect
11
+ @names = names
12
+ @names = @params.collect{|param| param[1] } if @names.empty?
13
+ end
14
+
15
+ def pre_initialize method, object, exitstatus, *args
16
+ param_args = AssignParams.new(object).assign args, @params
17
+ @names.each{|name|
18
+ object.instance_variable_set :"@#{name.to_s.sub /^@/, ''}", param_args[name]
19
+ }
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,58 @@
1
+ # coding=utf-8
2
+
3
+ using AutoAttrInit::Refinments
4
+
5
+ module AutoAttrInit
6
+ # classを静的解析して、initializeのparamsを抽出する。
7
+ class DetectParams
8
+ # @param klass [Class]
9
+ def initialize klass
10
+ @klass = klass
11
+ end
12
+
13
+ # @return [Array] [param type, param name, default value|nil][]
14
+ def detect
15
+ initialize_method = @klass.instance_method :initialize
16
+ if initialize_method
17
+ params = initialize_method.parameters
18
+ params = analyze_opt_params initialize_method, params
19
+ params = params.select{|param| param[0] != :block }
20
+ else
21
+ params = []
22
+ end
23
+ params
24
+ end
25
+
26
+ private
27
+ # opt paramとkey paramのdefault値を解析し、其れを含めたparamsを返却。
28
+ def analyze_opt_params method, params
29
+ params_sexp = detect_params_sexp method
30
+ params_sexp.zip params do |sexp, param|
31
+ next unless [:opt, :key].include?(param[0])
32
+ param << sorcerer(sexp)
33
+ end
34
+ params
35
+ end
36
+
37
+ # methodの、params部のS式 (SExp) を取得する。
38
+ def detect_params_sexp method
39
+ params_sexp =
40
+ Ripper.sexp_raw(method.source_code).
41
+ find_deep{|sexp| sexp.has_method?(:[]) && sexp[0] == :params }.
42
+ select{|sexp| sexp != nil }
43
+ params_sexp = params_sexp[1..-1].inject [] do |accm, sexp|
44
+ if sexp[0].is_a? Symbol
45
+ accm << sexp
46
+ else
47
+ accm += sexp
48
+ end
49
+ accm
50
+ end
51
+ end
52
+
53
+ # S式からsource code文字列を復元する。
54
+ def sorcerer sexp
55
+ Sorcerer.source sexp[1]
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,10 @@
1
+ # coding=utf-8
2
+
3
+ require 'ripper'
4
+ require 'sorcerer'
5
+ require 'aspectr'
6
+ require "#{__dir__}/refinments.rb"
7
+ require "#{__dir__}/detect_params.rb"
8
+ require "#{__dir__}/assign_params.rb"
9
+ require "#{__dir__}/auto_ai_aspect.rb"
10
+ require "#{__dir__}/auto_ai.rb"
@@ -0,0 +1,49 @@
1
+ # coding=utf-8
2
+
3
+ module AutoAttrInit
4
+ # Utility refinments for this AutoAttrInit.
5
+ module Refinments
6
+ refine Object do
7
+ # @param name [Stirng]
8
+ # @return [Boolean]
9
+ def has_method? name
10
+ methods.any?{|m| m.to_s == name.to_s }
11
+ end
12
+ end
13
+
14
+ refine UnboundMethod do
15
+ # method本体のsource codeを文字列で取得する。
16
+ # @return [String]
17
+ def source_code
18
+ source = ''
19
+ File.open source_location[0], 'r:utf-8' do |f|
20
+ lines = f.read.each_line.to_a
21
+ source = lines[source_location[1] - 1]
22
+ (source_location[1] .. lines.length - 1).each do |i|
23
+ break if Ripper.sexp_raw(source, source_location[0], source_location[1])
24
+ source += lines[i]
25
+ end
26
+ end
27
+ source
28
+ end
29
+ end
30
+
31
+ refine Array do
32
+ # Array#detect のdeep search版。
33
+ # @return [Object|nil]
34
+ def detect_deep ifnone = ->{ nil }, &p
35
+ target = nil
36
+ each do |elm|
37
+ (target = elm; break) if p.call(elm)
38
+ next unless elm.has_method?(:find_deep)
39
+ v = elm.detect_deep ifnone, &p
40
+ (target = v; break) if v != nil
41
+ nil
42
+ end
43
+ target
44
+ end
45
+
46
+ alias find_deep detect_deep
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,5 @@
1
+ # license: Public Domain
2
+
3
+ module AutoAttrInit
4
+ VERSION = "0.0.1"
5
+ end
@@ -0,0 +1,129 @@
1
+ # coding=utf-8
2
+
3
+ class TestAutoAttrInit < Test::Unit::TestCase
4
+ def test_AutoAttrInit_can_set_instance_variables
5
+ creq = Class.new do
6
+ attr_reader :a, :b, :c
7
+ def initialize a, b, c
8
+ end
9
+ auto_attr_init :a, :c
10
+ end
11
+ c_req = creq.new 4, 5, 6
12
+ assert_equal 4, c_req.a
13
+ assert_nil c_req.b
14
+ assert_equal 6, c_req.c
15
+
16
+ creq = Class.new do
17
+ attr_reader :a, :b
18
+ def initialize a, b, &p
19
+ end
20
+ auto_attr_init
21
+ end
22
+ c_req = creq.new(2, 3){|q| q }
23
+ assert_equal 2, c_req.a
24
+ assert_equal 3, c_req.b
25
+ end
26
+
27
+ def test_AutoAttrInit_can_work_for_optional_params
28
+ copt = Class.new do
29
+ attr_reader :a, :b
30
+ def initialize a = 2, b = 3
31
+ end
32
+ auto_attr_init
33
+ end
34
+ c_opt = copt.new 4
35
+ assert_equal 4, c_opt.a
36
+ assert_equal 3, c_opt.b
37
+ c_opt = copt.new
38
+ assert_equal 2, c_opt.a
39
+ assert_equal 3, c_opt.b
40
+ end
41
+
42
+ def test_AutoAttrInit_can_work_for_rest_param
43
+ crest = Class.new do
44
+ attr_reader :r
45
+ def initialize *r
46
+ end
47
+ auto_attr_init
48
+ end
49
+ c_rest = crest.new 2, 3
50
+ assert_equal [2, 3], c_rest.r
51
+ c_rest = crest.new
52
+ assert_equal [], c_rest.r
53
+
54
+ crest = Class.new do
55
+ attr_reader :a, :b, :r
56
+ def initialize a, *r, b
57
+ end
58
+ auto_attr_init
59
+ end
60
+ c_rest = crest.new 2, 3, 4, 5
61
+ assert_equal 2, c_rest.a
62
+ assert_equal [3, 4], c_rest.r
63
+ assert_equal 5, c_rest.b
64
+ end
65
+
66
+ def test_AutoAttrInit_can_work_for_hash_param
67
+ chash = Class.new do
68
+ attr_reader :h
69
+ def initialize h = {}
70
+ end
71
+ auto_attr_init
72
+ end
73
+ c_hash = chash.new p1: 'p1', p2: 'p2'
74
+ assert_equal({ p1: 'p1', p2: 'p2' }, c_hash.h)
75
+ end
76
+
77
+ def test_AutoAttrInit_can_work_on_keyword_params
78
+ ckey = Class.new do
79
+ attr_reader :p1, :p2
80
+ def initialize *, p1: 'p1d', p2: 'p2d'
81
+ end
82
+ auto_attr_init
83
+ end
84
+ c_key = ckey.new p1: 'p1', p2: 'p2'
85
+ assert_equal 'p1', c_key.p1
86
+ assert_equal 'p2', c_key.p2
87
+ c_key = ckey.new p2: 'p2'
88
+ assert_equal 'p1d', c_key.p1
89
+ assert_equal 'p2', c_key.p2
90
+
91
+ ckey = Class.new do
92
+ attr_reader :p1, :p2
93
+ def initialize *, p1: 'p1d', p2: 'p2d', **opt
94
+ end
95
+ auto_attr_init
96
+ def method_missing name, *args, &p
97
+ @opt[name]
98
+ end
99
+ end
100
+ c_key = ckey.new p1: 'p1', p3: 'p3'
101
+ assert_equal 'p1', c_key.p1
102
+ assert_equal 'p2d', c_key.p2
103
+ assert_equal 'p3', c_key.p3
104
+ end
105
+
106
+ def test_AutoAttrInit_can_work_on_keyword_params_with_opt_params
107
+ ckeyopt = Class.new do
108
+ attr_reader :a, :p1
109
+ def initialize a = 3, p1: 'p1d'
110
+ end
111
+ auto_attr_init
112
+ end
113
+ c_keyopt = ckeyopt.new
114
+ assert_equal 3, c_keyopt.a
115
+ assert_equal 'p1d', c_keyopt.p1
116
+ end
117
+
118
+ # https://github.com/ne-sachirou/AutoAttrInit.rb/issues/3
119
+ def test_AutoAttrInit_by_atmark_prefix
120
+ cat = Class.new do
121
+ attr_reader :a, :b, :c
122
+ def initialize @a, b, @c = 9; end
123
+ end
124
+ c_at = cat.new 2, 3
125
+ assert_equal 2, c_at.a
126
+ assert_nil c_at.b
127
+ assert_equal 9, c_at.c
128
+ end
129
+ end
@@ -0,0 +1,10 @@
1
+ # coding=utf-8
2
+
3
+ using AutoAttrInit::Refinments
4
+
5
+ class TestArray < Test::Unit::TestCase
6
+ def test_find_deep
7
+ assert_equal 4, [2, 3, [4]].find_deep{|e| e == 4 }
8
+ assert_nil [2, 3, [4]].find_deep{|e| e == 5 }
9
+ end
10
+ end
@@ -0,0 +1 @@
1
+ # coding=utf-8
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: auto_attr_init
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - ne_Sachirou
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-10-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aspectr
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: sorcerer
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: test-unit
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Auto attribute initialization.
84
+ email:
85
+ - utakata.c4se@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - .editorconfig
91
+ - .gitignore
92
+ - Gemfile
93
+ - README.markdown
94
+ - Rakefile
95
+ - auto_attr_init.gemspec
96
+ - lib/auto_attr_init.rb
97
+ - lib/auto_attr_init/assign_params.rb
98
+ - lib/auto_attr_init/auto_ai.rb
99
+ - lib/auto_attr_init/auto_ai_aspect.rb
100
+ - lib/auto_attr_init/detect_params.rb
101
+ - lib/auto_attr_init/main.rb
102
+ - lib/auto_attr_init/refinments.rb
103
+ - lib/auto_attr_init/version.rb
104
+ - test/auto_attr_init/test_auto_ai.rb
105
+ - test/auto_attr_init/test_refinments.rb
106
+ - test/helper.rb
107
+ homepage: https://github.com/ne-sachirou/AutoAttrInit.rb
108
+ licenses:
109
+ - Public Domain
110
+ metadata: {}
111
+ post_install_message:
112
+ rdoc_options: []
113
+ require_paths:
114
+ - lib
115
+ required_ruby_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - '>='
118
+ - !ruby/object:Gem::Version
119
+ version: 2.0.0
120
+ required_rubygems_version: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '>='
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ requirements: []
126
+ rubyforge_project:
127
+ rubygems_version: 2.0.3
128
+ signing_key:
129
+ specification_version: 4
130
+ summary: Dart and CoffeeScript like "automatic field initialization" in Ruby.
131
+ test_files:
132
+ - test/auto_attr_init/test_auto_ai.rb
133
+ - test/auto_attr_init/test_refinments.rb
134
+ - test/helper.rb