attic 0.3.1 → 0.6.pre.RC1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: cab1b37cf99fda2d7f47b898c998af908e2c8f4dcdde31ae66cd34d7c337a993
4
+ data.tar.gz: 7d579f1320f3493b6639705d316aaf1197f77aa20894ecff84abd0a34a162124
5
+ SHA512:
6
+ metadata.gz: 920f145e1b3eb27151653a69be076fe3224c82e2781695209e2017ac4634708855dc0331ad254a9765bd185f25e566b1c6a712bc6118668c201ec0fa240239fc
7
+ data.tar.gz: e0e4204bd76ae3f76c7c3a51166c278f69b2152db651a2ccd28ce8d559f281bfbf18e253713608fad2d9d488b96f52d3397070de7cc606842c3f47971db1276a
data/README.md ADDED
@@ -0,0 +1,54 @@
1
+ # Attic - v0.6-RC1 (2021-07-01)
2
+
3
+ A place to hide private instance variables in your Ruby objects.
4
+
5
+ ## Example
6
+
7
+ ```ruby
8
+ require 'attic'
9
+
10
+ class String
11
+ extend Attic
12
+ attic :timestamp
13
+ end
14
+
15
+ a = "anything"
16
+ a.timestamp = "1980-11-18"
17
+ a.instance_variables # => []
18
+ a.timestamp # 1980-11-18
19
+
20
+ a.attic_variables # => [:timestamp]
21
+
22
+ a.attic_variable_set :tags, [:a, :b, :c]
23
+ a.attic_variable_get :tags # [:a, :b, :c]
24
+
25
+ a.attic_variables # => [:timestamp, :tags]
26
+ ```
27
+
28
+ ## Some objects have no metaclasses
29
+
30
+ Symbol objects do not have metaclasses so instance variables are hidden in the object itself.
31
+
32
+
33
+ ## Installation
34
+
35
+ Via Rubygems, one of:
36
+
37
+ ```shell
38
+ $ gem install attic
39
+ ```
40
+
41
+ or via download:
42
+ * attic-latest.tar.gz[http://github.com/delano/attic/tarball/latest]
43
+ * attic-latest.zip[http://github.com/delano/attic/zipball/latest]
44
+
45
+
46
+ ## Credits
47
+
48
+ * `gems@solutious.com` (@delano)
49
+
50
+
51
+ ## License
52
+
53
+ MIT
54
+
data/Rakefile CHANGED
@@ -1,18 +1,16 @@
1
1
  require 'rubygems'
2
2
  require 'rake/clean'
3
- require 'rake/gempackagetask'
4
- require 'rake/rdoctask'
3
+ require 'rubygems/package_task'
5
4
  require 'fileutils'
5
+ require 'rdoc/task'
6
6
  include FileUtils
7
-
7
+
8
8
  task :default => :package
9
-
9
+
10
10
  # CONFIG =============================================================
11
11
 
12
12
  # Change the following according to your needs
13
- README = "README.rdoc"
14
- CHANGES = "CHANGES.txt"
15
- LICENSE = "LICENSE.txt"
13
+ README = "README.md"
16
14
 
17
15
  # Files and directories to be deleted when you run "rake clean"
18
16
  CLEAN.include [ 'pkg', '*.gem', '.config']
@@ -23,7 +21,7 @@ load "#{name}.gemspec"
23
21
  version = @spec.version
24
22
 
25
23
  # That's it! The following defaults should allow you to get started
26
- # on other things.
24
+ # on other things.
27
25
 
28
26
 
29
27
  # TESTS/SPECS =========================================================
@@ -32,7 +30,7 @@ version = @spec.version
32
30
 
33
31
  # INSTALL =============================================================
34
32
 
35
- Rake::GemPackageTask.new(@spec) do |p|
33
+ Gem::PackageTask.new(@spec) do |p|
36
34
  p.need_tar = true if RUBY_PLATFORM !~ /mswin/
37
35
  end
38
36
 
@@ -45,25 +43,6 @@ task :uninstall => [ :clean ] do
45
43
  end
46
44
 
47
45
 
48
- # RUBYFORGE RELEASE / PUBLISH TASKS ==================================
49
-
50
- if @spec.rubyforge_project
51
- desc 'Publish website to rubyforge'
52
- task 'publish:rdoc' => 'doc/index.html' do
53
- sh "scp -rp doc/* rubyforge.org:/var/www/gforge-projects/#{name}/"
54
- end
55
-
56
- desc 'Public release to rubyforge'
57
- task 'publish:gem' => [:package] do |t|
58
- sh <<-end
59
- rubyforge add_release -o Any -a #{CHANGES} -f -n #{README} #{name} #{name} #{@spec.version} pkg/#{name}-#{@spec.version}.gem &&
60
- rubyforge add_file -o Any -a #{CHANGES} -f -n #{README} #{name} #{name} #{@spec.version} pkg/#{name}-#{@spec.version}.tgz
61
- end
62
- end
63
- end
64
-
65
-
66
-
67
46
  # RUBY DOCS TASK ==================================
68
47
 
69
48
  Rake::RDocTask.new do |t|
@@ -71,10 +50,7 @@ Rake::RDocTask.new do |t|
71
50
  t.title = @spec.summary
72
51
  t.options << '--line-numbers' << '-A cattr_accessor=object'
73
52
  t.options << '--charset' << 'utf-8'
74
- t.rdoc_files.include(LICENSE)
75
53
  t.rdoc_files.include(README)
76
- t.rdoc_files.include(CHANGES)
77
- #t.rdoc_files.include('bin/*')
78
54
  t.rdoc_files.include('lib/**/*.rb')
79
55
  end
80
56
 
data/attic.gemspec CHANGED
@@ -1,57 +1,20 @@
1
1
  @spec = Gem::Specification.new do |s|
2
2
  s.name = "attic"
3
- s.rubyforge_project = "attic"
4
- s.version = "0.3.1"
5
- s.summary = "A place for Ruby objects to hide instance variables."
6
- s.description = s.summary
3
+ s.version = "0.6-RC1"
4
+ s.summary = "When in doubt, store it in the attic"
5
+ s.description = "Attic: a place to hide metadata about the class or variable itself (e.g. SHA hash summaries)."
7
6
  s.author = "Delano Mandelbaum"
8
- s.email = "delano@solutious.com"
7
+ s.email = "gems@solutious.com"
9
8
  s.homepage = "http://github.com/delano/attic"
10
-
11
- # = EXECUTABLES =
12
- # The list of executables in your project (if any). Don't include the path,
13
- # just the base filename.
14
9
  s.executables = %w[]
15
-
16
- # Directories to extract rdocs from
17
- s.require_paths = %w[lib]
18
-
19
- # Specific files to include rdocs from
20
- s.extra_rdoc_files = %w[README.rdoc LICENSE.txt CHANGES.txt]
21
-
22
- # Update --main to reflect the default page to display
23
- s.rdoc_options = ["--line-numbers", "--title", s.summary, "--main", "README.rdoc"]
24
-
25
- # = DEPENDENCIES =
26
- # Add all gem dependencies
27
- #s.add_dependency 'name1'
28
- #s.add_dependency 'name2', '>= 0.0.0'
29
-
30
- # = MANIFEST =
31
- # The complete list of files to be included in the release. When GitHub packages your gem,
32
- # it doesn't allow you to run any command that accesses the filesystem. You will get an
33
- # error. You can ask your VCS for the list of versioned files:
34
- # git ls-files
35
- # svn list -R
10
+ s.require_paths = %w[lib]
11
+ s.extra_rdoc_files = %w[README.md]
12
+ s.licenses = ["MIT"] # https://spdx.org/licenses/MIT-Modern-Variant.html
13
+ s.rdoc_options = ["--line-numbers", "--title", s.summary, "--main", "README.md"]
36
14
  s.files = %w(
37
- CHANGES.txt
38
- LICENSE.txt
39
- README.rdoc
40
- Rakefile
41
- attic.gemspec
42
- lib/attic.rb
43
- lib/attic/mixins.rb
44
- lib/attic/mixins/object.rb
45
- try/01_mixins_tryouts.rb
46
- try/10_attic_tryouts.rb
47
- try/20_accessing_tryouts.rb
48
- try/25_string_tryouts.rb
49
- try/30_nometaclass_tryouts.rb
50
- try/metaclasses.rb
15
+ README.md
16
+ Rakefile
17
+ attic.gemspec
18
+ lib/attic.rb
51
19
  )
52
-
53
- s.has_rdoc = true
54
- s.rubygems_version = '1.3.0'
55
-
56
-
57
- end
20
+ end
data/lib/attic.rb CHANGED
@@ -1,82 +1,205 @@
1
1
 
2
- require 'attic/mixins'
2
+ class NoMetaClass < RuntimeError
3
+ end
4
+
5
+ # = Object
6
+ #
7
+ # These methods are copied directly from _why's metaid.rb.
8
+ # See: http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html
9
+ class Object
10
+
11
+ unless defined?(::Object::NOMETACLASS)
12
+ # An Array of classes which do not have metaclasses.
13
+ NOMETACLASS = [Symbol, Integer]
14
+ end
15
+
16
+ def nometaclass?
17
+ NOMETACLASS.member?(self)
18
+ end
19
+
20
+ def metaclass?
21
+ !NOMETACLASS.member?(self.class)
22
+ end
23
+
24
+ # A convenient method for getting the metaclass of the current object.
25
+ # i.e.
26
+ #
27
+ # class << self; self; end;
28
+ #
29
+ # NOTE: Some Ruby class do not have meta classes (see: NOMETACLASS).
30
+ # For these classes, this method returns the class itself. That means
31
+ # the instance variables will be stored in the class itself.
32
+ def metaclass
33
+ if self.metaclass?
34
+ class << self
35
+ self
36
+ end
37
+ else
38
+ self
39
+ end
40
+ end
41
+
42
+ def metaclassfly
43
+ location = self.class
44
+ attr_name = "@@_attic_#{self.object_id}"
45
+ unless location.class_variable_defined? attr_name
46
+ location.class_variable_set attr_name, Class.new
47
+ end
48
+ location.class_variable_get attr_name
49
+ end
50
+
51
+ # Execute a block +&blk+ within the metaclass of the current object.
52
+ def meta_eval &blk
53
+ metaclass.instance_eval blk
54
+ end
55
+
56
+ # Add an instance method called +name+ to metaclass for the current object.
57
+ # This is useful because it will be available as a singleton method
58
+ # to all subclasses too.
59
+ def meta_def name, &blk
60
+ meta_eval { define_method name, &blk }
61
+ end
62
+
63
+ # Add a class method called +name+ for the current object's class. This
64
+ # isn't so special but it maintains consistency with meta_def.
65
+ def class_def name, &blk
66
+ class_eval { define_method name, &blk }
67
+ end
68
+
69
+
70
+ # A convenient method for getting the metaclass of the metaclass
71
+ # i.e.
72
+ #
73
+ # self.metaclass.metaclass
74
+ #
75
+ def metametaclass
76
+ self.metaclass.metaclass
77
+ end
78
+
79
+ def metameta_eval &blk
80
+ metametaclass.instance_eval blk
81
+ end
82
+
83
+ def metameta_def name, &blk
84
+ metameta_eval { define_method name, &blk }
85
+ end
86
+ end
87
+
88
+
3
89
 
4
90
  # = Attic
5
91
  #
6
- # A place to store instance variables.
92
+ # A place to store instance variables.
7
93
  #
8
94
  module Attic
9
- VERSION = '0.3.1'
10
-
95
+ VERSION = '0.6-RC1' unless defined?(VERSION)
96
+
97
+ module InstanceMethods
98
+ def attic_variables
99
+ self.class.attic_variables
100
+ end
101
+ alias_method :attic_vars, :attic_variables
102
+ def attic_variable? n
103
+ self.class.attic_variable? n
104
+ end
105
+ def attic_variable_set(n,v)
106
+ attic_variables << n unless attic_variable? n
107
+ # binding.pry
108
+ metaclassfly.instance_variable_set("@___attic_#{n}", v)
109
+ end
110
+ def attic_variable_get(n)
111
+ metaclassfly.instance_variable_get("@___attic_#{n}")
112
+ end
113
+ def get_binding
114
+ binding
115
+ end
116
+ end
117
+
11
118
  def self.included(o)
12
119
  raise "You probably meant to 'extend Attic' in #{o}"
13
120
  end
14
-
121
+
15
122
  def self.extended(o)
16
- ## NOTE: This is just a reminder for a more descerning way to
17
- ## include the meta methods, instead of using a global mixin.
18
- ##o.class_eval do
19
- ## include ObjectHelpers
20
- ##end
21
-
22
- # Create an instance method that returns the attic variables.
123
+ # This class has already been extended.
124
+ return if o.ancestors.member? Attic::InstanceMethods
125
+
126
+ # Add the instance methods for accessing attic variables
127
+ o.send :include, Attic::InstanceMethods
128
+
129
+ o.metaclass.instance_variable_set("@attic_variables", [])
23
130
  o.class_eval do
24
- define_method :attic_vars do
25
- self.class.attic_vars
131
+ def self.inherited(o2)
132
+ attic_vars = self.attic_variables.clone
133
+ o2.metaclass.instance_variable_set("@attic_variables", attic_vars)
134
+ end
135
+ if method_defined? :instance_variables
136
+ old_instance_variables = instance_method(:instance_variables)
137
+ define_method :instance_variables do
138
+ ret = old_instance_variables.bind(self).call.clone
139
+ ret.reject! { |v| v.to_s =~ /^@___?attic/ } # match 2 or 3 underscores
140
+ ret
141
+ end
142
+ define_method :all_instance_variables do
143
+ old_instance_variables.bind(self).call
144
+ end
26
145
  end
27
146
  end
28
147
  end
29
-
30
- # A class method for defining variables to store in the attic.
31
- # * +junk+ is a list of variables names. Accessor methods are
32
- # created for each variable name in the list.
33
- #
148
+
149
+ # A class method for defining variables to store in the attic.
150
+ # * +junk+ is a list of variables names. Accessor methods are
151
+ # created for each variable name in the list.
152
+ #
34
153
  # Returns the list of attic variable names or if not junk was
35
- # given, returns the metaclass.
154
+ # given, returns the metaclass.
36
155
  #
37
156
  # e.g.
38
- #
157
+ #
39
158
  # String.extend Attic
40
159
  # String.attic :timestamp
41
160
  #
42
161
  # In this example, attic created two instance methods:
43
- # * +String#timestamp+ for getting the value
44
- # * +String#timestamp+ for setting the value
162
+ # * <tt>String#timestamp</tt> for getting the value
163
+ # * <tt>String#timestamp</tt> for setting the value
45
164
  #
46
165
  def attic *junk
47
166
  return metaclass if junk.empty?
48
-
49
- # Add the attic variables named to the list. Notice that we
50
- # cheakily store this in the metameta class so as to not
51
- # disturb the metaclass instance variables.
52
- metametaclass.instance_variable_set("@attic", [attic_vars, *junk].flatten)
53
-
54
167
  junk.each do |name|
55
- class_eval do
168
+ next if attic_variable? name
169
+ self.attic_variables << name
170
+
171
+ unless method_defined? name
56
172
  define_method(name) do
57
- metaclass.instance_variable_get("@#{name}")
173
+ attic_variable_get name
58
174
  end
175
+ end
176
+ unless method_defined? "#{name}="
59
177
  define_method("#{name}=") do |val|
60
- metaclass.instance_variable_set("@#{name}", val)
178
+ attic_variable_set name, val
61
179
  end
62
180
  end
63
181
  end
64
-
65
182
  attic_vars
66
183
  end
67
-
68
- # Returns an Array of attic variables for the current class.
184
+
185
+ # Returns an Array of attic variables for the current class.
69
186
  # e.g.
70
187
  #
71
188
  # String.extend Attic
72
189
  # String.attic :timestamp
73
- # String.attic_vars # => [:timestamp]
190
+ # String.attic_variables # => [:timestamp]
74
191
  #
75
- def attic_vars
76
- metametaclass.instance_variable_get("@attic") || []
192
+ def attic_variables
193
+ a = self.metaclass.instance_variable_get("@attic_variables")
194
+ a ||= self.metaclass.instance_variable_set("@attic_variables", [])
195
+ a
77
196
  end
78
-
79
-
197
+ alias_method :attic_vars, :attic_variables
198
+
199
+ def attic_variable?(n)
200
+ attic_variables.member? n
201
+ end
202
+
80
203
  end
81
204
 
82
205
  # - Module#instance_method returns an UnboundMethod
metadata CHANGED
@@ -1,74 +1,53 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: attic
3
- version: !ruby/object:Gem::Version
4
- version: 0.3.1
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.6.pre.RC1
5
5
  platform: ruby
6
- authors:
6
+ authors:
7
7
  - Delano Mandelbaum
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
-
12
- date: 2009-07-13 00:00:00 -04:00
13
- default_executable:
11
+ date: 2021-07-22 00:00:00.000000000 Z
14
12
  dependencies: []
15
-
16
- description: A place for Ruby objects to hide instance variables.
17
- email: delano@solutious.com
13
+ description: 'Attic: a place to hide metadata about the class or variable itself (e.g.
14
+ SHA hash summaries).'
15
+ email: gems@solutious.com
18
16
  executables: []
19
-
20
17
  extensions: []
21
-
22
- extra_rdoc_files:
23
- - README.rdoc
24
- - LICENSE.txt
25
- - CHANGES.txt
26
- files:
27
- - CHANGES.txt
28
- - LICENSE.txt
29
- - README.rdoc
18
+ extra_rdoc_files:
19
+ - README.md
20
+ files:
21
+ - README.md
30
22
  - Rakefile
31
23
  - attic.gemspec
32
24
  - lib/attic.rb
33
- - lib/attic/mixins.rb
34
- - lib/attic/mixins/object.rb
35
- - try/01_mixins_tryouts.rb
36
- - try/10_attic_tryouts.rb
37
- - try/20_accessing_tryouts.rb
38
- - try/25_string_tryouts.rb
39
- - try/30_nometaclass_tryouts.rb
40
- - try/metaclasses.rb
41
- has_rdoc: true
42
25
  homepage: http://github.com/delano/attic
43
- licenses: []
44
-
26
+ licenses:
27
+ - MIT
28
+ metadata: {}
45
29
  post_install_message:
46
- rdoc_options:
47
- - --line-numbers
48
- - --title
49
- - A place for Ruby objects to hide instance variables.
50
- - --main
51
- - README.rdoc
52
- require_paths:
30
+ rdoc_options:
31
+ - "--line-numbers"
32
+ - "--title"
33
+ - When in doubt, store it in the attic
34
+ - "--main"
35
+ - README.md
36
+ require_paths:
53
37
  - lib
54
- required_ruby_version: !ruby/object:Gem::Requirement
55
- requirements:
38
+ required_ruby_version: !ruby/object:Gem::Requirement
39
+ requirements:
56
40
  - - ">="
57
- - !ruby/object:Gem::Version
58
- version: "0"
59
- version:
60
- required_rubygems_version: !ruby/object:Gem::Requirement
61
- requirements:
62
- - - ">="
63
- - !ruby/object:Gem::Version
64
- version: "0"
65
- version:
41
+ - !ruby/object:Gem::Version
42
+ version: '0'
43
+ required_rubygems_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.3.1
66
48
  requirements: []
67
-
68
- rubyforge_project: attic
69
- rubygems_version: 1.3.2
49
+ rubygems_version: 3.2.21
70
50
  signing_key:
71
- specification_version: 3
72
- summary: A place for Ruby objects to hide instance variables.
51
+ specification_version: 4
52
+ summary: When in doubt, store it in the attic
73
53
  test_files: []
74
-
data/CHANGES.txt DELETED
@@ -1,17 +0,0 @@
1
- ATTIC, CHANGES
2
-
3
- #### 0.3.1 (2009-07-13) ###############################
4
-
5
- CRIPES! I'd forgotten to update the gemspec.
6
-
7
-
8
- #### 0.3 (2009-07-11) ###############################
9
-
10
- NOTE: A complete re-write from 0.2
11
-
12
- * FIXED: Now works on any Object except Symbol and Fixnum
13
- * ADDED: attic_vars method
14
-
15
- #### 0.2 (2009-07-08) ###############################
16
-
17
- NOTE: Initial public release
data/LICENSE.txt DELETED
@@ -1,19 +0,0 @@
1
- Copyright (c) 2009 Solutious Inc, Delano Mandelbaum
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining a copy
4
- of this software and associated documentation files (the "Software"), to deal
5
- in the Software without restriction, including without limitation the rights
6
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- copies of the Software, and to permit persons to whom the Software is
8
- furnished to do so, subject to the following conditions:
9
-
10
- The above copyright notice and this permission notice shall be included in
11
- all copies or substantial portions of the Software.
12
-
13
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- THE SOFTWARE.
data/README.rdoc DELETED
@@ -1,42 +0,0 @@
1
- = Attic - v0.3 ALPHA
2
-
3
- A place for Ruby objects to hide instance variables.
4
-
5
- == Alpha Notice
6
-
7
- This library is fresh (est 2009-07-06) and barely tested. It's fun to use but not reliable yet. In particular:
8
-
9
- * Does not work with Symbols or Fixnum object
10
-
11
- == Example
12
-
13
- require 'attic'
14
-
15
- String.extend Attic
16
- String.attic :timestamp
17
-
18
- a = "anything"
19
- a.timestamp = "1980-11-18"
20
- a.instance_variables # => []
21
- a.timestamp # 1980-11-18
22
-
23
-
24
- == Installation
25
-
26
- Via Rubygems, one of:
27
-
28
- $ gem install attic
29
- $ gem install delano-attic --source http://gems.github.com/
30
-
31
- or via download:
32
- * attic-latest.tar.gz[http://github.com/delano/attic/tarball/latest]
33
- * attic-latest.zip[http://github.com/delano/attic/zipball/latest]
34
-
35
-
36
- == Credits
37
-
38
- * Delano (@solutious.com)
39
-
40
- == License
41
-
42
- See: LICENSE.txt
data/lib/attic/mixins.rb DELETED
@@ -1,3 +0,0 @@
1
-
2
- require 'attic/mixins/object'
3
-
@@ -1,57 +0,0 @@
1
-
2
- # = Object
3
- #
4
- # These methods are copied directly from _why's metaid.rb.
5
- # See: http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html
6
- class Object
7
-
8
- # An Array of classes which do not have metaclasses.
9
- NOMETACLASS = [Symbol, Fixnum].freeze
10
-
11
- # A convenient method for getting the metaclass of the current object.
12
- # i.e.
13
- #
14
- # class << self; self; end;
15
- #
16
- # NOTE: Some Ruby class do not have meta classes (see: NOMETACLASS).
17
- # For these classes, this method returns the class itself. That means
18
- # the instance variables will stored in the class itself.
19
- def metaclass;
20
- if NOMETACLASS.member? self.class
21
- self.class
22
- else
23
- class << self; self; end;
24
- end
25
- end
26
-
27
- # Execute a block +&blk+ within the metaclass of the current object.
28
- def meta_eval &blk; metaclass.instance_eval &blk; end
29
-
30
- # Add an instance method called +name+ to metaclass for the current object.
31
- # This is useful because it will be available as a singleton method
32
- # to all subclasses too.
33
- def meta_def name, &blk
34
- meta_eval { define_method name, &blk }
35
- end
36
-
37
- # Add a class method called +name+ for the current object's class. This
38
- # isn't so special but it maintains consistency with meta_def.
39
- def class_def name, &blk
40
- class_eval { define_method name, &blk }
41
- end
42
-
43
-
44
- # A convenient method for getting the metaclass of the metaclass
45
- # i.e.
46
- #
47
- # self.metaclass.metaclass
48
- #
49
- def metametaclass; self.metaclass.metaclass; end
50
-
51
- def metameta_eval &blk; metametaclass.instance_eval &blk; end
52
-
53
- def metameta_def name, &blk
54
- metameta_eval { define_method name, &blk }
55
- end
56
-
57
- end
@@ -1,12 +0,0 @@
1
- group "Mixins"
2
- library :attic, 'lib'
3
-
4
- tryouts "Object" do
5
- drill "has metaclass", 'Object' do
6
- Object.new.metaclass.superclass.to_s
7
- end
8
-
9
- drill "has metametaclass", '#<Class:Object>' do
10
- Object.new.metametaclass.superclass.to_s
11
- end
12
- end
@@ -1,28 +0,0 @@
1
- group "Attic"
2
- library :attic, "lib"
3
- tryouts "Basics" do
4
-
5
- drill "can extend Attic", true do
6
- class ::Worker
7
- extend Attic
8
- end
9
- Worker.methods.member? :attic
10
- end
11
-
12
- drill "can't include Attic raises exception", :exception, RuntimeError do
13
- class ::Worker
14
- include Attic
15
- end
16
- end
17
-
18
- drill "can define attic attribute", true do
19
- Worker.attic :size
20
- w = Worker.new
21
- #w.attic :size
22
- stash :methods, w.methods.sort
23
- stash :metamethods, Worker.methods.sort
24
- w.respond_to? :size
25
- end
26
-
27
- end
28
-
@@ -1,34 +0,0 @@
1
- group "Attic"
2
- library :attic, "lib"
3
- tryouts "Setting and Getting" do
4
-
5
- setup do
6
- class ::Worker
7
- extend Attic
8
- attic :size
9
- end
10
- end
11
-
12
- drill "save an instance variable the long way", 'S&F' do
13
- w = Worker.new
14
- w.metametaclass.instance_variable_set '@mattress', 'S&F'
15
- w.metametaclass.instance_variable_get '@mattress'
16
- end
17
-
18
- drill "save an instance variable the short way", :california_king do
19
- w = Worker.new
20
- w.size = :california_king
21
- w.size
22
- end
23
-
24
- drill "new instances don't cross streams", nil do
25
- w = Worker.new
26
- w.size
27
- end
28
-
29
- drill "instance variables are hidden", [] do
30
- w = Worker.new
31
- w.metametaclass.instance_variable_set '@mattress', 'S&F'
32
- w.instance_variables
33
- end
34
- end
@@ -1,38 +0,0 @@
1
- group "Attic"
2
- library :attic, "lib"
3
- tryouts "String Setting and Getting" do
4
-
5
- drill "String can extend Attic", true do
6
- String.extend Attic
7
- String.respond_to? :attic
8
- end
9
-
10
- drill "save an instance variable the long way", 'S&F' do
11
- s = ""
12
- s.metametaclass.instance_variable_set '@mattress', 'S&F'
13
- s.metametaclass.instance_variable_get '@mattress'
14
- end
15
-
16
- drill "can create attributes", [:goodies] do
17
- String.attic :goodies
18
- end
19
-
20
- drill "save an instance variable the short way", :california_king do
21
- s = ""
22
- s.goodies = :california_king
23
- stash :ivars, s.instance_variables
24
- stash :avars, s.attic_vars
25
- s.goodies
26
- end
27
-
28
- drill "String instances don't cross streams", false do
29
- String.extend Attic
30
- String.attic :name
31
- a = "any"
32
- a.name = :roger
33
- a.name == "".name
34
- end
35
-
36
-
37
-
38
- end
@@ -1,24 +0,0 @@
1
- group "No Meta Class"
2
- library :attic, 'lib'
3
- tryouts "Basics" do
4
-
5
- dream :class, Array
6
- dream [Symbol, Fixnum]
7
- drill "has list of no metaclass classes" do
8
- Object::NOMETACLASS
9
- end
10
-
11
- drill "Symbol metaclass returns Symbol", Symbol do
12
- :any.metaclass
13
- end
14
-
15
- ## NOTE: fails
16
- drill "Symbol instances don't cross streams", true do
17
- Symbol.extend Attic
18
- Symbol.attic :name
19
- a = :any
20
- a.name = :roger
21
- [a.name, :another.name]
22
- end
23
-
24
- end
data/try/metaclasses.rb DELETED
@@ -1,112 +0,0 @@
1
- # $ ruby tryouts/metaclasses.rb
2
-
3
- class Object
4
-
5
- # A convenient method for getting the metaclass of the current object.
6
- # i.e.
7
- #
8
- # class << self; self; end;
9
- #
10
- def metaclass; class << self; self; end; end
11
-
12
- # Execute a block +&blk+ within the metaclass of the current object.
13
- def meta_eval &blk; metaclass.instance_eval &blk; end
14
-
15
- # Add an instance method called +name+ to metaclass for the current object.
16
- # This is useful because it will be available as a singleton method
17
- # to all subclasses too.
18
- def meta_def name, &blk
19
- meta_eval { define_method name, &blk }
20
- end
21
-
22
- # Add a class method called +name+ for the current object's class. This
23
- # isn't so special but it maintains consistency with meta_def.
24
- def class_def name, &blk
25
- class_eval { define_method name, &blk }
26
- end
27
-
28
-
29
- # A convenient method for getting the metaclass of the metaclass
30
- # i.e.
31
- #
32
- # self.metaclass.metaclass
33
- #
34
- def metametaclass; self.metaclass.metaclass; end
35
-
36
- def metameta_eval &blk; metametaclass.instance_eval &blk; end
37
-
38
- def metameta_def name, &blk
39
- metameta_eval { define_method name, &blk }
40
- end
41
-
42
- end
43
-
44
- # Create an instance method
45
- class NamedArray1
46
- class_eval do
47
- define_method(:name) do
48
- :roger
49
- end
50
- end
51
- end
52
- p [1, NamedArray1.new.name]
53
-
54
- # Create getter and setter instance methods
55
- class NamedArray2
56
- class_eval do
57
- define_method(:name) do
58
- instance_variable_get("@name")
59
- end
60
- define_method(:name=) do |val|
61
- instance_variable_set("@name", val)
62
- end
63
- end
64
- end
65
- a = NamedArray2.new
66
- a.name = :roger
67
- p [2, a.name, a.instance_variables]
68
-
69
- # Create getter and setter instance methods,
70
- # store instance variable in metaclass
71
- class NamedArray3
72
- class_eval do
73
- define_method(:name) do
74
- metaclass.instance_variable_get("@name")
75
- end
76
- define_method(:name=) do |val|
77
- metaclass.instance_variable_set("@name", val)
78
- end
79
- end
80
- end
81
- a = NamedArray3.new
82
- a.name = :roger
83
- p [3, a.name, a.instance_variables, a.metaclass.instance_variables]
84
-
85
- # Create a module with the which puts the functionality
86
- # in NamedArray3 into a class method.
87
- module StorageArea
88
- def store *junk
89
- junk.each do |name|
90
- class_eval do
91
- define_method(name) do
92
- metaclass.instance_variable_get("@#{name}")
93
- end
94
- define_method("#{name}=") do |val|
95
- metaclass.instance_variable_set("@#{name}", val)
96
- end
97
- end
98
- end
99
- end
100
- end
101
- class NamedArray4
102
- extend StorageArea
103
- store :name
104
- end
105
- a = NamedArray4.new
106
- a.name = :roger
107
- p [4, a.name, a.instance_variables, a.metaclass.instance_variables]
108
-
109
-
110
-
111
-
112
-