elliottcable-refinery 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.
@@ -0,0 +1,126 @@
1
+ Refinery
2
+ ========
3
+ Refinery stemmed from a very specific need that arose while writing
4
+ [attr_*][] — to be able to utilize the Ruby hooks (for example, the
5
+ `method_added` and `method_missing` methods) without “gobbling them up” so to
6
+ speak. Normally, had I used those methods (especially if my particular
7
+ implementation was very dependent on these methods operating in a specific
8
+ way), the person using my library would be precluded from using the same
9
+ methods in whatever class they included/extended my library into; if they used
10
+ one of those methods for some purpose, their definition would ‘overwrite’ mine,
11
+ thus quite possibly making my library (or their code using my library) cease
12
+ to function correctly.
13
+
14
+ The simple, singular purpose of Refinery is to ‘refine’ methods in such a way
15
+ that your important functionality can be assigned safely to these methods.
16
+ Any attempts to re-define a ‘refined’ method after the refining process will
17
+ simply ‘stack’ with your own implementation — your method code will execute
18
+ first, with further re-definitions each being executed in turn when the method
19
+ is called.
20
+
21
+ [attr_*]: <http://by.elliottcable.name/attr_splat.xhtml> "elliottcable's attr_splat project"
22
+
23
+ Usage
24
+ -----
25
+ Using Refinery is very simple - extend it into your class (or include it into
26
+ the Class class if you use it often), and then pass a method's name (as a
27
+ symbol) to the refine_method singleton method. A short example:
28
+
29
+ class Something
30
+ extend Refinery
31
+
32
+ def method_missing meth, *args
33
+ # Do some magic!
34
+ puts 'abc'
35
+ end
36
+
37
+ refine_method :method_missing
38
+ end
39
+
40
+ # Later, somewhere else…
41
+
42
+ class Nothing < Something
43
+ def method_missing meth, *args
44
+ # Do other magic, not knowing about the former magic!
45
+ puts 'def'
46
+ end
47
+ end
48
+
49
+ nothing = Nothing.new
50
+ nothing.nonexistant_method
51
+
52
+ Once refined, any further re-openings of your class (or a descendant) and
53
+ re-definitions of the refined method will simply result in the implementations
54
+ 'stacking' with eachother.
55
+
56
+ Care must obviously still be taken to ensure your code will 'stack' in a
57
+ friendly way with the other implementations — be sure to programmatically
58
+ check whatever may be necessary before executing your method's code!
59
+
60
+ Installation
61
+ ------------
62
+ You can install Refinery as a pre-built gem, or as a gem generated directly
63
+ from the source.
64
+
65
+ The easiest way to install Refinery is to use [RubyGems][] to acquire the
66
+ latest 'release' version from [RubyForge][], using the `gem` command line tool:
67
+
68
+ sudo gem install refinery # You'll be asked for your account password.
69
+
70
+ Alternatively, you can acquire it (possibly slightly more up-to-date,
71
+ depending on how often I update the gemspec) from GitHub as follows:
72
+
73
+ # If you've ever done this before, you don't need to do it now - see http://gems.github.com
74
+ gem sources -a http://gems.github.com
75
+ sudo gem install elliottcable-refinery # You'll be asked for your account password.
76
+
77
+ Finally, you can build a gem from the latest source yourself. You need [git][],
78
+ as well as [rake][]:
79
+
80
+ git clone git://github.com/elliottcable/refinery.git
81
+ cd refinery
82
+ # If you've ever done this before, you don't need to do it now - see http://gems.github.com
83
+ gem sources -a http://gems.github.com
84
+ sudo gem install elliottcable-echoe # You'll be asked for your account password.
85
+ rake install # You'll be asked for your account password.
86
+
87
+ [RubyGems]: <http://rubyforge.org/projects/rubygems/> "RubyGems - Ruby package manager"
88
+ [RubyForge]: <http://rubyforge.org/projects/refinery/> "Refinery on RubyForge"
89
+ [git]: <http://git-scm.com/> "git - Fast Version Control System"
90
+
91
+ Contributing
92
+ ------------
93
+ You can contribute bug fixes or new features to Refinery by forking the project
94
+ on GitHub (you'll need to register for an account first), and sending me a
95
+ pull request once you've committed your changes.
96
+
97
+ Links
98
+ -----
99
+ - [GitHub](http://github.com/elliottcable/refinery "Refinery on GitHub") is the
100
+ project's primary repository host, and currently also the project's home
101
+ page
102
+ - [RubyForge](http://rubyforge.org/projects/refinery "Refinery on RubyForge") is
103
+ out primary RubyGem host, as well as an alternative repository host
104
+ - [integrity](http://integrit.yreality.net/refinery "Refinery on yreality's integrity server")
105
+ is out continuous integration server - if the top build on that page is
106
+ green, you can assume the latest git HEAD is safe to run/install/utilize.
107
+ - [Gitorious](http://gitorious.org/projects/refinery "Refinery on Gitorious") is
108
+ an alternative repository host
109
+ - [repo.or.cz](http://repo.or.cz/w/refinery.git "Refinery on repo.or.cz") is
110
+ an alternative repository host
111
+
112
+ Attribution
113
+ -----------
114
+ The Sing extension was contributed by [John Mair][banisterfiend].
115
+
116
+ [banisterfiend]: <http://banisterfiend.wordpress.com/> "Banisterfiend (John Mair)'s Weblog"
117
+
118
+ License
119
+ -------
120
+ Refinery is copyright 2008 by elliott cable.
121
+
122
+ Refinery is released under the [GNU General Public License v3.0][gpl], which
123
+ allows you to freely utilize, modify, and distribute all Refinery's source code
124
+ (subject to the terms of the aforementioned license).
125
+
126
+ [gpl]: <http://www.gnu.org/licenses/gpl.txt> "The GNU General Public License v3.0"
@@ -0,0 +1,134 @@
1
+ ($:.unshift File.expand_path(File.join( File.dirname(__FILE__), 'lib' ))).uniq!
2
+ begin
3
+ require 'refinery'
4
+ rescue LoadError
5
+ module Refinery; Version = -1; end
6
+ end
7
+
8
+ # =======================
9
+ # = Gem packaging tasks =
10
+ # =======================
11
+ begin
12
+ require 'echoe'
13
+
14
+ task :package => :'package:install'
15
+ task :manifest => :'package:manifest'
16
+ namespace :package do
17
+ Echoe.new('refinery', Refinery::Version) do |g|; g.name = 'Refinery'
18
+ g.project = 'refinery'
19
+ g.author = ['elliottcable']
20
+ g.email = ['Refinery@elliottcable.com']
21
+ g.summary = 'Mmmmagic'
22
+ g.url = 'http://github.com/elliottcable/refinery'
23
+ g.development_dependencies = ['elliottcable-echoe >= 3.0.2', 'rspec', 'rcov', 'yard', 'stringray']
24
+ g.manifest_name = '.manifest'
25
+ g.retain_gemspec = true
26
+ g.rakefile_name = 'Rakefile.rb'
27
+ g.ignore_pattern = /^\.git\/|^meta\/|\.gemspec/
28
+ end
29
+
30
+ desc 'tests packaged files to ensure they are all present'
31
+ task :verify => :package do
32
+ # An error message will be displayed if files are missing
33
+ if system %(ruby -e "require 'rubygems'; require 'pkg/refinery-#{Refinery::Version}/lib/refinery'")
34
+ puts "\nThe library files are present"
35
+ end
36
+ end
37
+ end
38
+
39
+ rescue LoadError
40
+ desc 'You need the `elliottcable-echoe` gem to package Refinery'
41
+ task :package
42
+ end
43
+
44
+ # =======================
45
+ # = Spec/Coverage tasks =
46
+ # =======================
47
+ begin
48
+ require 'spec'
49
+ require 'rcov'
50
+ require 'spec/rake/spectask'
51
+
52
+ task :default => :'coverage:run'
53
+ task :coverage => :'coverage:run'
54
+ namespace :coverage do
55
+ Spec::Rake::SpecTask.new(:run) do |t|
56
+ t.spec_opts = ["--format", "specdoc"]
57
+ t.spec_opts << "--colour" unless ENV['CI']
58
+ t.spec_files = Dir['spec/**/*_spec.rb'].sort
59
+ t.libs = ['lib']
60
+ t.rcov = true
61
+ t.rcov_opts = [ '--include-file', '"^lib"', '--exclude-only', '".*"']
62
+ t.rcov_dir = File.join('meta', 'coverage')
63
+ end
64
+
65
+ begin
66
+ require 'spec/rake/verify_rcov'
67
+ # For the moment, this is the only way I know of to fix RCov. I may
68
+ # release the fix as it's own gem at some point in the near future.
69
+ require 'stringray/core_ext/spec/rake/verify_rcov'
70
+ RCov::VerifyTask.new(:verify) do |t|
71
+ t.threshold = 95.0
72
+ t.index_html = File.join('meta', 'coverage', 'index.html')
73
+ t.require_exact_threshold = false
74
+ end
75
+ rescue LoadError
76
+ desc 'You need the `stringray` gem to verify coverage'
77
+ task :verify
78
+ end
79
+
80
+ task :open do
81
+ system 'open ' + File.join('meta', 'coverage', 'index.html') if PLATFORM['darwin']
82
+ end
83
+ end
84
+
85
+ rescue LoadError
86
+ desc 'You need the `rcov` and `rspec` gems to run specs/coverage'
87
+ task :coverage
88
+ end
89
+
90
+ # =======================
91
+ # = Documentation tasks =
92
+ # =======================
93
+ begin
94
+ require 'yard'
95
+ require 'yard/rake/yardoc_task'
96
+
97
+ task :documentation => :'documentation:generate'
98
+ namespace :documentation do
99
+ YARD::Rake::YardocTask.new :generate do |t|
100
+ t.files = ['lib/**/*.rb']
101
+ t.options = ['--output-dir', File.join('meta', 'documentation'),
102
+ '--readme', 'README.markdown']
103
+ end
104
+
105
+ YARD::Rake::YardocTask.new :dotyardoc do |t|
106
+ t.files = ['lib/**/*.rb']
107
+ t.options = ['--no-output',
108
+ '--readme', 'README.markdown']
109
+ end
110
+
111
+ task :open do
112
+ system 'open ' + File.join('meta', 'documentation', 'index.html') if PLATFORM['darwin']
113
+ end
114
+ end
115
+
116
+ rescue LoadError
117
+ desc 'You need the `yard` gem to generate documentation'
118
+ task :documentation
119
+ end
120
+
121
+ # =========
122
+ # = Other =
123
+ # =========
124
+ desc 'Removes all meta producs'
125
+ task :clobber do
126
+ `rm -rf #{File.expand_path(File.join( File.dirname(__FILE__), 'meta' ))}`
127
+ end
128
+
129
+ desc 'Check everything over before commiting'
130
+ task :aok => [:'documentation:generate', :'documentation:open',
131
+ :'package:manifest', :'package:package', :'package:compile',
132
+ :'coverage:run', :'coverage:open', :'coverage:verify']
133
+
134
+ task :ci => [:'documentation:generate', :'coverage:run', :'coverage:verify']
@@ -0,0 +1,3 @@
1
+ require 'mkmf'
2
+
3
+ create_makefile("sing")
@@ -0,0 +1,13 @@
1
+ #include <ruby.h>
2
+ #include <stdio.h>
3
+
4
+ VALUE jm_Module;
5
+ VALUE singleton(VALUE self) {
6
+ if(FL_TEST(self, FL_SINGLETON)) return Qtrue;
7
+ else return Qfalse;
8
+ }
9
+
10
+ void Init_sing() {
11
+ jm_Module = rb_define_module("Sing");
12
+ rb_define_method(jm_Module,"singleton?",singleton,0);
13
+ }
@@ -0,0 +1,10 @@
1
+ require 'refinery/core_ext/class'
2
+
3
+ module Refinery
4
+ Version = 0
5
+
6
+ # This refines an instance method named 'meth'.
7
+ def refine_method meth
8
+
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ require 'sing'
2
+
3
+ class Class
4
+ # Pulls in #singleton?
5
+ include Sing
6
+
7
+ ##
8
+ # Returns a list of all instances of this class
9
+ def instances
10
+ ObjectSpace.each_object(self).to_a
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ class Object
2
+ ##
3
+ # Returns the singleton class for this object.
4
+ def singleton
5
+ class<<self;self;end
6
+ end
7
+ end
@@ -0,0 +1,128 @@
1
+
2
+ # Gem::Specification for Refinery-0
3
+ # Originally generated by Echoe
4
+
5
+ --- !ruby/object:Gem::Specification
6
+ name: refinery
7
+ version: !ruby/object:Gem::Version
8
+ version: "0"
9
+ platform: ruby
10
+ authors:
11
+ - elliottcable
12
+ autorequire:
13
+ bindir: bin
14
+
15
+ date: 2008-10-12 00:00:00 -08:00
16
+ default_executable:
17
+ dependencies:
18
+ - !ruby/object:Gem::Dependency
19
+ name: echoe
20
+ type: :development
21
+ version_requirement:
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 3.0.1
27
+ version:
28
+ - !ruby/object:Gem::Dependency
29
+ name: rspec
30
+ type: :development
31
+ version_requirement:
32
+ version_requirements: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - ">="
35
+ - !ruby/object:Gem::Version
36
+ version: "0"
37
+ version:
38
+ - !ruby/object:Gem::Dependency
39
+ name: rcov
40
+ type: :development
41
+ version_requirement:
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: "0"
47
+ version:
48
+ - !ruby/object:Gem::Dependency
49
+ name: yard
50
+ type: :development
51
+ version_requirement:
52
+ version_requirements: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: "0"
57
+ version:
58
+ - !ruby/object:Gem::Dependency
59
+ name: stringray
60
+ type: :development
61
+ version_requirement:
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: "0"
67
+ version:
68
+ description: Mmmmagic
69
+ email:
70
+ - Refinery@elliottcable.com
71
+ executables: []
72
+
73
+ extensions:
74
+ - ext/sing/extconf.rb
75
+ extra_rdoc_files:
76
+ - ext/sing/extconf.rb
77
+ - ext/sing/sing.c
78
+ - lib/refinery/core_ext/class.rb
79
+ - lib/refinery/core_ext/object.rb
80
+ - lib/refinery.rb
81
+ - LICENSE.text
82
+ - README.markdown
83
+ files:
84
+ - ext/sing/extconf.rb
85
+ - ext/sing/sing.c
86
+ - lib/refinery/core_ext/class.rb
87
+ - lib/refinery/core_ext/object.rb
88
+ - lib/refinery.rb
89
+ - LICENSE.text
90
+ - Rakefile.rb
91
+ - README.markdown
92
+ - spec/refinery/core_ext/class_spec.rb
93
+ - spec/refinery_spec.rb
94
+ - spec/spec_helper.rb
95
+ - .manifest
96
+ - refinery.gemspec
97
+ has_rdoc: true
98
+ homepage: http://github.com/elliottcable/refinery
99
+ post_install_message:
100
+ rdoc_options:
101
+ - --line-numbers
102
+ - --inline-source
103
+ - --title
104
+ - Refinery
105
+ - --main
106
+ - README.markdown
107
+ require_paths:
108
+ - lib
109
+ - ext
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: "0"
115
+ version:
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: "1.2"
121
+ version:
122
+ requirements: []
123
+
124
+ rubyforge_project: refinery
125
+ rubygems_version: 1.3.0
126
+ specification_version: 2
127
+ summary: Mmmmagic
128
+ test_files: []
@@ -0,0 +1,18 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Class do
4
+ describe '#is_singleton?' do
5
+
6
+ it 'should return false for a normal class' do
7
+ klass = Class.new
8
+ klass.should_not be_singleton
9
+ end
10
+
11
+ it 'should return true for a singleton class' do
12
+ klass = Class.new
13
+ sing = klass.class_eval { class << self; self; end }
14
+ sing.should be_singleton
15
+ end
16
+
17
+ end
18
+ end