thorero 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/History.txt +1 -0
  2. data/LICENSE +20 -0
  3. data/Manifest +45 -0
  4. data/Manifest.txt +29 -0
  5. data/README.txt +3 -0
  6. data/Rakefile +180 -0
  7. data/lib/extlib.rb +32 -0
  8. data/lib/extlib/assertions.rb +8 -0
  9. data/lib/extlib/blank.rb +42 -0
  10. data/lib/extlib/class.rb +175 -0
  11. data/lib/extlib/hash.rb +410 -0
  12. data/lib/extlib/hook.rb +366 -0
  13. data/lib/extlib/inflection.rb +141 -0
  14. data/lib/extlib/lazy_array.rb +106 -0
  15. data/lib/extlib/logger.rb +202 -0
  16. data/lib/extlib/mash.rb +143 -0
  17. data/lib/extlib/module.rb +37 -0
  18. data/lib/extlib/object.rb +165 -0
  19. data/lib/extlib/object_space.rb +13 -0
  20. data/lib/extlib/pathname.rb +5 -0
  21. data/lib/extlib/pooling.rb +233 -0
  22. data/lib/extlib/rubygems.rb +38 -0
  23. data/lib/extlib/simple_set.rb +39 -0
  24. data/lib/extlib/string.rb +132 -0
  25. data/lib/extlib/struct.rb +8 -0
  26. data/lib/extlib/tasks/release.rb +11 -0
  27. data/lib/extlib/time.rb +12 -0
  28. data/lib/extlib/version.rb +3 -0
  29. data/lib/extlib/virtual_file.rb +10 -0
  30. data/spec/blank_spec.rb +85 -0
  31. data/spec/hash_spec.rb +524 -0
  32. data/spec/hook_spec.rb +1198 -0
  33. data/spec/inflection_spec.rb +50 -0
  34. data/spec/lazy_array_spec.rb +896 -0
  35. data/spec/mash_spec.rb +244 -0
  36. data/spec/module_spec.rb +58 -0
  37. data/spec/object_space_spec.rb +9 -0
  38. data/spec/object_spec.rb +98 -0
  39. data/spec/pooling_spec.rb +486 -0
  40. data/spec/simple_set_spec.rb +26 -0
  41. data/spec/spec_helper.rb +8 -0
  42. data/spec/string_spec.rb +200 -0
  43. data/spec/struct_spec.rb +12 -0
  44. data/spec/time_spec.rb +16 -0
  45. data/spec/virtual_file_spec.rb +21 -0
  46. data/thorero.gemspec +147 -0
  47. metadata +146 -0
data/History.txt ADDED
@@ -0,0 +1 @@
1
+
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Sam Smoot.
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest ADDED
@@ -0,0 +1,45 @@
1
+ History.txt
2
+ lib/extlib/assertions.rb
3
+ lib/extlib/blank.rb
4
+ lib/extlib/class.rb
5
+ lib/extlib/hash.rb
6
+ lib/extlib/hook.rb
7
+ lib/extlib/inflection.rb
8
+ lib/extlib/lazy_array.rb
9
+ lib/extlib/logger.rb
10
+ lib/extlib/mash.rb
11
+ lib/extlib/module.rb
12
+ lib/extlib/object.rb
13
+ lib/extlib/object_space.rb
14
+ lib/extlib/pathname.rb
15
+ lib/extlib/pooling.rb
16
+ lib/extlib/rubygems.rb
17
+ lib/extlib/simple_set.rb
18
+ lib/extlib/string.rb
19
+ lib/extlib/struct.rb
20
+ lib/extlib/tasks/release.rb
21
+ lib/extlib/time.rb
22
+ lib/extlib/version.rb
23
+ lib/extlib/virtual_file.rb
24
+ lib/extlib.rb
25
+ LICENSE
26
+ Manifest.txt
27
+ Rakefile
28
+ README.txt
29
+ spec/blank_spec.rb
30
+ spec/hash_spec.rb
31
+ spec/hook_spec.rb
32
+ spec/inflection_spec.rb
33
+ spec/lazy_array_spec.rb
34
+ spec/mash_spec.rb
35
+ spec/module_spec.rb
36
+ spec/object_space_spec.rb
37
+ spec/object_spec.rb
38
+ spec/pooling_spec.rb
39
+ spec/simple_set_spec.rb
40
+ spec/spec_helper.rb
41
+ spec/string_spec.rb
42
+ spec/struct_spec.rb
43
+ spec/time_spec.rb
44
+ spec/virtual_file_spec.rb
45
+ Manifest
data/Manifest.txt ADDED
@@ -0,0 +1,29 @@
1
+ .autotest
2
+ History.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ lib/extlib.rb
7
+ lib/extlib/assertions.rb
8
+ lib/extlib/blank.rb
9
+ lib/extlib/hook.rb
10
+ lib/extlib/inflection.rb
11
+ lib/extlib/lazy_array.rb
12
+ lib/extlib/module.rb
13
+ lib/extlib/object.rb
14
+ lib/extlib/pathname.rb
15
+ lib/extlib/pooling.rb
16
+ lib/extlib/string.rb
17
+ lib/extlib/struct.rb
18
+ lib/extlib/version.rb
19
+ spec/blank_spec.rb
20
+ spec/hook_spec.rb
21
+ spec/inflection_spec.rb
22
+ spec/lazy_array_spec.rb
23
+ spec/module_spec.rb
24
+ spec/object_spec.rb
25
+ spec/pooling_spec.rb
26
+ spec/spec_helper.rb
27
+ spec/string_spec.rb
28
+ spec/struct_spec.rb
29
+ tasks/hoe.rb
data/README.txt ADDED
@@ -0,0 +1,3 @@
1
+ = extlib
2
+
3
+ A support library for DataMapper, DataObjects and Merb.
data/Rakefile ADDED
@@ -0,0 +1,180 @@
1
+ #!/usr/bin/env ruby
2
+ require 'pathname'
3
+ require 'rubygems'
4
+ require 'rake'
5
+ require "rake/clean"
6
+ require "rake/gempackagetask"
7
+ require "fileutils"
8
+ require Pathname('spec/rake/spectask')
9
+ require Pathname('lib/extlib/version')
10
+
11
+ ROOT = Pathname(__FILE__).dirname.expand_path
12
+
13
+ AUTHOR = "Test Test"
14
+ EMAIL = "test.test@gmail.com"
15
+
16
+ PROJECT_NAME = "thorero"
17
+ PROJECT_URL = "http://thorero.rubyforge.org"
18
+ PROJECT_DESCRIPTION = PROJECT_SUMMARY = "Support Library for DataMapper and DataObjects"
19
+
20
+ GEM_NAME = PROJECT_NAME
21
+ GEM_VERSION = Extlib::VERSION
22
+ GEM_DEPENDENCIES = [["english", ">=0.2.0"]]
23
+ GEM_EXTRAS = { :has_rdoc => false }
24
+
25
+ RUBY_FORGE_PROJECT = "release-task-playground"
26
+
27
+ PKG_NAME = GEM_NAME
28
+ PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
29
+ PKG_VERSION = Extlib::VERSION + PKG_BUILD
30
+ PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
31
+
32
+ RELEASE_NAME = "REL #{PKG_VERSION}"
33
+
34
+ begin
35
+ require 'echoe'
36
+
37
+ Echoe.new(PROJECT_NAME, Extlib::VERSION) do |p|
38
+ p.rubyforge_name = PROJECT_NAME
39
+
40
+ p.summary = PROJECT_SUMMARY
41
+ p.description = PROJECT_DESCRIPTION
42
+ p.url = PROJECT_URL
43
+ p.author = AUTHOR
44
+ p.email = EMAIL
45
+
46
+ # rdoc
47
+ p.has_rdoc = false
48
+ p.rdoc_pattern = /^(lib|bin|tasks|ext)|^README\.txt|^CHANGELOG|^TODO|^LICENSE$/
49
+
50
+ p.dependencies = ["english >=0.2.0"]
51
+ end
52
+
53
+ rescue LoadError => boom
54
+ puts "You are missing a dependency required for meta-operations on this gem."
55
+ puts "#{boom.to_s.capitalize}."
56
+ end
57
+
58
+
59
+ task :default => 'extlib:spec'
60
+ task :spec => 'extlib:spec'
61
+
62
+ desc 'Remove all package, docs and spec products'
63
+ task :clobber_all => %w[ clobber_package clobber_doc extlib:clobber_spec ]
64
+
65
+ namespace :extlib do
66
+ Spec::Rake::SpecTask.new(:spec) do |t|
67
+ t.spec_opts << '--format' << 'specdoc' << '--colour'
68
+ t.spec_opts << '--loadby' << 'random'
69
+ t.spec_files = Pathname.glob(ENV['FILES'] || 'spec/**/*_spec.rb')
70
+
71
+ begin
72
+ t.rcov = ENV.has_key?('NO_RCOV') ? ENV['NO_RCOV'] != 'true' : true
73
+ t.rcov_opts << '--exclude' << 'spec'
74
+ t.rcov_opts << '--text-summary'
75
+ t.rcov_opts << '--sort' << 'coverage' << '--sort-reverse'
76
+ rescue Exception
77
+ # rcov not installed
78
+ end
79
+ end
80
+ end
81
+
82
+ desc "Generate documentation"
83
+ task :doc do
84
+ begin
85
+ require 'yard'
86
+ exec 'yardoc'
87
+ rescue LoadError
88
+ puts 'You will need to install the latest version of Yard to generate the
89
+ documentation for extlib.'
90
+ end
91
+ end
92
+
93
+ WINDOWS = (RUBY_PLATFORM =~ /win32|mingw|bccwin|cygwin/) rescue nil
94
+ SUDO = WINDOWS ? '' : ('sudo' unless ENV['SUDOLESS'])
95
+
96
+ desc "Install #{GEM_NAME}"
97
+ task :install => :package do
98
+ sh %{#{SUDO} gem install --local pkg/#{GEM_NAME}-#{GEM_VERSION} --no-update-sources}
99
+ end
100
+
101
+ if WINDOWS
102
+ namespace :dev do
103
+ desc 'Install for development (for windows)'
104
+ task :winstall => :gem do
105
+ system %{gem install --no-rdoc --no-ri -l pkg/#{GEM_NAME}-#{GEM_VERSION}.gem}
106
+ end
107
+ end
108
+ end
109
+
110
+ namespace :ci do
111
+
112
+ task :prepare do
113
+ rm_rf ROOT + "ci"
114
+ mkdir_p ROOT + "ci"
115
+ mkdir_p ROOT + "ci/doc"
116
+ mkdir_p ROOT + "ci/cyclomatic"
117
+ mkdir_p ROOT + "ci/token"
118
+ end
119
+
120
+ task :publish do
121
+ out = ENV['CC_BUILD_ARTIFACTS'] || "out"
122
+ mkdir_p out unless File.directory? out
123
+
124
+ mv "ci/unit_rspec_report.html", "#{out}/unit_rspec_report.html"
125
+ mv "ci/unit_coverage", "#{out}/unit_coverage"
126
+ mv "ci/integration_rspec_report.html", "#{out}/integration_rspec_report.html"
127
+ mv "ci/integration_coverage", "#{out}/integration_coverage"
128
+ mv "ci/doc", "#{out}/doc"
129
+ mv "ci/cyclomatic", "#{out}/cyclomatic_complexity"
130
+ mv "ci/token", "#{out}/token_complexity"
131
+ end
132
+
133
+
134
+ Spec::Rake::SpecTask.new("spec:unit" => :prepare) do |t|
135
+ t.spec_opts = ["--format", "specdoc", "--format", "html:#{ROOT}/ci/unit_rspec_report.html", "--diff"]
136
+ t.spec_files = Pathname.glob(ROOT + "spec/unit/**/*_spec.rb")
137
+ unless ENV['NO_RCOV']
138
+ t.rcov = true
139
+ t.rcov_opts << '--exclude' << "spec,gems"
140
+ t.rcov_opts << '--text-summary'
141
+ t.rcov_opts << '--sort' << 'coverage' << '--sort-reverse'
142
+ t.rcov_opts << '--only-uncovered'
143
+ end
144
+ end
145
+
146
+ Spec::Rake::SpecTask.new("spec:integration" => :prepare) do |t|
147
+ t.spec_opts = ["--format", "specdoc", "--format", "html:#{ROOT}/ci/integration_rspec_report.html", "--diff"]
148
+ t.spec_files = Pathname.glob(ROOT + "spec/integration/**/*_spec.rb")
149
+ unless ENV['NO_RCOV']
150
+ t.rcov = true
151
+ t.rcov_opts << '--exclude' << "spec,gems"
152
+ t.rcov_opts << '--text-summary'
153
+ t.rcov_opts << '--sort' << 'coverage' << '--sort-reverse'
154
+ t.rcov_opts << '--only-uncovered'
155
+ end
156
+ end
157
+
158
+ task :spec do
159
+ Rake::Task["ci:spec:unit"].invoke
160
+ mv ROOT + "coverage", ROOT + "ci/unit_coverage"
161
+
162
+ Rake::Task["ci:spec:integration"].invoke
163
+ mv ROOT + "coverage", ROOT + "ci/integration_coverage"
164
+ end
165
+
166
+ task :doc do
167
+ require 'yardoc'
168
+ sh 'yardoc'
169
+ end
170
+
171
+ task :saikuro => :prepare do
172
+ system "saikuro -c -i lib -y 0 -w 10 -e 15 -o ci/cyclomatic"
173
+ mv 'ci/cyclomatic/index_cyclo.html', 'ci/cyclomatic/index.html'
174
+
175
+ system "saikuro -t -i lib -y 0 -w 20 -e 30 -o ci/token"
176
+ mv 'ci/token/index_token.html', 'ci/token/index.html'
177
+ end
178
+ end
179
+
180
+ task :ci => ["ci:spec", "ci:doc", "ci:saikuro", :install, :publish]
data/lib/extlib.rb ADDED
@@ -0,0 +1,32 @@
1
+ require 'pathname'
2
+ require 'rubygems'
3
+
4
+ __DIR__ = File.expand_path(File.dirname(__FILE__))
5
+ $LOAD_PATH.unshift(__DIR__) unless $LOAD_PATH.include?(__DIR__)
6
+
7
+ # for Pathname /
8
+ require File.expand_path(File.join(__DIR__, 'extlib', 'pathname'))
9
+
10
+ dir = Pathname(__FILE__).dirname.expand_path / 'extlib'
11
+
12
+ require dir / "class.rb"
13
+ require dir / "object"
14
+ require dir / "object_space"
15
+
16
+ require dir / "string"
17
+ require dir / "hash"
18
+ require dir / "mash"
19
+ require dir / "virtual_file"
20
+ require dir / "logger"
21
+ require dir / "time"
22
+
23
+ require dir / 'assertions'
24
+ require dir / 'blank'
25
+ require dir / 'inflection'
26
+ require dir / 'lazy_array'
27
+ require dir / 'module'
28
+ require dir / 'blank'
29
+ require dir / 'pooling'
30
+ require dir / 'simple_set'
31
+ require dir / 'struct'
32
+ require dir / 'hook'
@@ -0,0 +1,8 @@
1
+ module Extlib
2
+ module Assertions
3
+ def assert_kind_of(name, value, *klasses)
4
+ klasses.each { |k| return if value.kind_of?(k) }
5
+ raise ArgumentError, "+#{name}+ should be #{klasses.map { |k| k.name } * ' or '}, but was #{value.class.name}", caller(2)
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,42 @@
1
+ # blank? methods for several different class types
2
+ class Object
3
+ # Returns true if the object is nil or empty (if applicable)
4
+ def blank?
5
+ nil? || (respond_to?(:empty?) && empty?)
6
+ end
7
+ end # class Object
8
+
9
+ class Numeric
10
+ # Numerics can't be blank
11
+ def blank?
12
+ false
13
+ end
14
+ end # class Numeric
15
+
16
+ class NilClass
17
+ # Nils are always blank
18
+ def blank?
19
+ true
20
+ end
21
+ end # class NilClass
22
+
23
+ class TrueClass
24
+ # True is not blank.
25
+ def blank?
26
+ false
27
+ end
28
+ end # class TrueClass
29
+
30
+ class FalseClass
31
+ # False is always blank.
32
+ def blank?
33
+ true
34
+ end
35
+ end # class FalseClass
36
+
37
+ class String
38
+ # Strips out whitespace then tests if the string is empty.
39
+ def blank?
40
+ strip.empty?
41
+ end
42
+ end # class String
@@ -0,0 +1,175 @@
1
+ # Copyright (c) 2004-2008 David Heinemeier Hansson
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining
4
+ # a copy of this software and associated documentation files (the
5
+ # "Software"), to deal in the Software without restriction, including
6
+ # without limitation the rights to use, copy, modify, merge, publish,
7
+ # distribute, sublicense, and/or sell copies of the Software, and to
8
+ # permit persons to whom the Software is furnished to do so, subject to
9
+ # the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be
12
+ # included in all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
22
+ # Allows attributes to be shared within an inheritance hierarchy, but where
23
+ # each descendant gets a copy of their parents' attributes, instead of just a
24
+ # pointer to the same. This means that the child can add elements to, for
25
+ # example, an array without those additions being shared with either their
26
+ # parent, siblings, or children, which is unlike the regular class-level
27
+ # attributes that are shared across the entire hierarchy.
28
+ class Class
29
+ # Defines class-level and instance-level attribute reader.
30
+ #
31
+ # @param *syms<Array> Array of attributes to define reader for.
32
+ # @return <Array[#to_s]> List of attributes that were made into cattr_readers
33
+ #
34
+ # @api public
35
+ #
36
+ # @todo Is this inconsistent in that it does not allow you to prevent
37
+ # an instance_reader via :instance_reader => false
38
+ def cattr_reader(*syms)
39
+ syms.flatten.each do |sym|
40
+ next if sym.is_a?(Hash)
41
+ class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
42
+ unless defined? @@#{sym}
43
+ @@#{sym} = nil
44
+ end
45
+
46
+ def self.#{sym}
47
+ @@#{sym}
48
+ end
49
+
50
+ def #{sym}
51
+ @@#{sym}
52
+ end
53
+ RUBY
54
+ end
55
+ end
56
+
57
+ # Defines class-level (and optionally instance-level) attribute writer.
58
+ #
59
+ # @param <Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to define writer for.
60
+ # @option syms :instance_writer<Boolean> if true, instance-level attribute writer is defined.
61
+ # @return <Array[#to_s]> List of attributes that were made into cattr_writers
62
+ #
63
+ # @api public
64
+ def cattr_writer(*syms)
65
+ options = syms.last.is_a?(Hash) ? syms.pop : {}
66
+ syms.flatten.each do |sym|
67
+ class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
68
+ unless defined? @@#{sym}
69
+ @@#{sym} = nil
70
+ end
71
+
72
+ def self.#{sym}=(obj)
73
+ @@#{sym} = obj
74
+ end
75
+ RUBY
76
+
77
+ unless options[:instance_writer] == false
78
+ class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
79
+ def #{sym}=(obj)
80
+ @@#{sym} = obj
81
+ end
82
+ RUBY
83
+ end
84
+ end
85
+ end
86
+
87
+ # Defines class-level (and optionally instance-level) attribute accessor.
88
+ #
89
+ # @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to define accessor for.
90
+ # @option syms :instance_writer<Boolean> if true, instance-level attribute writer is defined.
91
+ # @return <Array[#to_s]> List of attributes that were made into accessors
92
+ #
93
+ # @api public
94
+ def cattr_accessor(*syms)
95
+ cattr_reader(*syms)
96
+ cattr_writer(*syms)
97
+ end
98
+
99
+ # Defines class-level inheritable attribute reader. Attributes are available to subclasses,
100
+ # each subclass has a copy of parent's attribute.
101
+ #
102
+ # @param *syms<Array[#to_s]> Array of attributes to define inheritable reader for.
103
+ # @return <Array[#to_s]> Array of attributes converted into inheritable_readers.
104
+ #
105
+ # @api public
106
+ #
107
+ # @todo Do we want to block instance_reader via :instance_reader => false
108
+ # @todo It would be preferable that we do something with a Hash passed in
109
+ # (error out or do the same as other methods above) instead of silently
110
+ # moving on). In particular, this makes the return value of this function
111
+ # less useful.
112
+ def class_inheritable_reader(*ivars)
113
+ instance_reader = ivars.pop[:reader] if ivars.last.is_a?(Hash)
114
+
115
+ ivars.each do |ivar|
116
+ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
117
+ def self.#{ivar}
118
+ return @#{ivar} if self == #{self} || defined?(@#{ivar})
119
+ ivar = superclass.#{ivar}
120
+ return nil if ivar.nil? && !#{self}.instance_variable_defined?("@#{ivar}")
121
+ @#{ivar} = ivar && !ivar.is_a?(Module) ? ivar.dup : ivar
122
+ end
123
+ RUBY
124
+ unless instance_reader == false
125
+ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
126
+ def #{ivar}
127
+ self.class.#{ivar}
128
+ end
129
+ RUBY
130
+ end
131
+ end
132
+ end
133
+
134
+ # Defines class-level inheritable attribute writer. Attributes are available to subclasses,
135
+ # each subclass has a copy of parent's attribute.
136
+ #
137
+ # @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to
138
+ # define inheritable writer for.
139
+ # @option syms :instance_writer<Boolean> if true, instance-level inheritable attribute writer is defined.
140
+ # @return <Array[#to_s]> An Array of the attributes that were made into inheritable writers.
141
+ #
142
+ # @api public
143
+ #
144
+ # @todo We need a style for class_eval <<-HEREDOC. I'd like to make it
145
+ # class_eval(<<-RUBY, __FILE__, __LINE__), but we should codify it somewhere.
146
+ def class_inheritable_writer(*ivars)
147
+ instance_writer = ivars.pop[:instance_writer] if ivars.last.is_a?(Hash)
148
+ ivars.each do |ivar|
149
+ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
150
+ def self.#{ivar}=(obj)
151
+ @#{ivar} = obj
152
+ end
153
+ RUBY
154
+ unless instance_writer == false
155
+ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
156
+ def #{ivar}=(obj) self.class.#{ivar} = obj end
157
+ RUBY
158
+ end
159
+ end
160
+ end
161
+
162
+ # Defines class-level inheritable attribute accessor. Attributes are available to subclasses,
163
+ # each subclass has a copy of parent's attribute.
164
+ #
165
+ # @param *syms<Array[*#to_s, Hash{:instance_writer => Boolean}]> Array of attributes to
166
+ # define inheritable accessor for.
167
+ # @option syms :instance_writer<Boolean> if true, instance-level inheritable attribute writer is defined.
168
+ # @return <Array[#to_s]> An Array of attributes turned into inheritable accessors.
169
+ #
170
+ # @api public
171
+ def class_inheritable_accessor(*syms)
172
+ class_inheritable_reader(*syms)
173
+ class_inheritable_writer(*syms)
174
+ end
175
+ end