partialclass 0.1.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.
- data/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +74 -0
- data/Rakefile +8 -0
- data/lib/partialclass/version.rb +3 -0
- data/lib/partialclass.rb +26 -0
- data/partialclass.gemspec +22 -0
- data/test/common.rb +4 -0
- data/test/test_correctness.rb +21 -0
- data/test/test_interface.rb +15 -0
- metadata +93 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Simon Worthington
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Partial Classes
|
2
|
+
|
3
|
+
This gem allows you to specify arguments to a class before you
|
4
|
+
actually initialize it. This is useful for two main reasons:
|
5
|
+
|
6
|
+
1. It means you can specify initializer arguments ahead of time,
|
7
|
+
cutting down on the number of variables you need to pass around
|
8
|
+
or wrapper classes you need to manually write.
|
9
|
+
2. You can write a base class that takes initializer arguments
|
10
|
+
and then generate more specific child classes by specifying the
|
11
|
+
required arguments.
|
12
|
+
|
13
|
+
This is particularly useful if your class performs some some kind
|
14
|
+
of memory- or resource-hungry action in it's initializer that you
|
15
|
+
want to save until later (e.g. `File.new` opens the file straight
|
16
|
+
away).
|
17
|
+
|
18
|
+
The key point about all this is that you still get to pass around
|
19
|
+
classes, not `Proc`s or anything else, so you will still get the
|
20
|
+
behaviour that you expect a class to have. See the Usage
|
21
|
+
section for more information.
|
22
|
+
|
23
|
+
If the idea of this confuses or disorientates you, stop usage
|
24
|
+
immedieatly and seek medial assistance.
|
25
|
+
|
26
|
+
## Installation
|
27
|
+
|
28
|
+
Add this line to your application's Gemfile:
|
29
|
+
|
30
|
+
gem 'partialclass'
|
31
|
+
|
32
|
+
And then execute:
|
33
|
+
|
34
|
+
$ bundle
|
35
|
+
|
36
|
+
Or install it yourself as:
|
37
|
+
|
38
|
+
$ gem install partialclass
|
39
|
+
|
40
|
+
## Usage
|
41
|
+
|
42
|
+
require 'partialclass'
|
43
|
+
|
44
|
+
You can use `specialize` to generate a specialized child class:
|
45
|
+
|
46
|
+
Logfile = File.specialize "mylog.txt" # No files open yet
|
47
|
+
...
|
48
|
+
f = Logfile.new 'w' # File opened here!
|
49
|
+
|
50
|
+
You can also use the `<<` operator to push arguments to the class:
|
51
|
+
|
52
|
+
SpecificDay = Time << 2009 << 10 << 25
|
53
|
+
puts SpecificDay.new # 2009-10-25 00:00:00 +0100
|
54
|
+
puts SpecificDay.new 22, 35 # 2009-10-25 22:35:00 +0100
|
55
|
+
|
56
|
+
You can also specialize classes multiple times:
|
57
|
+
|
58
|
+
SpecificMinute = SpecificDay << 22 << 35
|
59
|
+
puts SpecificMinute.new 06 # 2009-10-25 22:35:06 +0100
|
60
|
+
|
61
|
+
Specialized classes are child classes of the original:
|
62
|
+
|
63
|
+
SpecificDay.superclass # Time
|
64
|
+
|
65
|
+
In many cases there maybe another way of acheiving this effect. If
|
66
|
+
you don't like this way, then don't use it!
|
67
|
+
|
68
|
+
## Contributing
|
69
|
+
|
70
|
+
1. Fork it
|
71
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
72
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
73
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
74
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/partialclass.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require "partialclass/version"
|
2
|
+
|
3
|
+
class Class
|
4
|
+
def specialize(*args)
|
5
|
+
_specialize(self, *args)
|
6
|
+
end
|
7
|
+
|
8
|
+
def << (arg)
|
9
|
+
specialize(arg)
|
10
|
+
end
|
11
|
+
|
12
|
+
unless Class.respond_to? :define_singleton_method
|
13
|
+
def define_singleton_method name, &block
|
14
|
+
metaclass = class << self; self; end
|
15
|
+
metaclass.define_method(:name, &block)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
def _specialize(parent, *prep)
|
21
|
+
Class.new(parent) do
|
22
|
+
define_method(:initialize) { |*args| super(*(prep + args)) }
|
23
|
+
define_singleton_method(:specialize) { |*args| _specialize(parent, *(prep+args)) }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'partialclass/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "partialclass"
|
8
|
+
spec.version = PartialClass::VERSION
|
9
|
+
spec.authors = ["Simon Worthington"]
|
10
|
+
spec.email = ["simon@simonwo.net"]
|
11
|
+
spec.summary = "Specialise a Ruby class by providing some of its initializer arguments or attributes ahead of time."
|
12
|
+
spec.homepage = "https://github.com/simonwo/partialclass"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files`.split($/)
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
+
spec.require_paths = ["lib"]
|
19
|
+
|
20
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
21
|
+
spec.add_development_dependency "rake"
|
22
|
+
end
|
data/test/common.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require_relative "common.rb"
|
3
|
+
require_relative "../lib/partialclass.rb"
|
4
|
+
|
5
|
+
class CorrectnessTests < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@Class = TestClass << 1 << 2 << 3
|
8
|
+
@Instance = @Class.new 4, 5, 6
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_method_inheritence
|
12
|
+
assert_respond_to @Instance, :mymethod
|
13
|
+
assert_equal "123456", @Instance.mymethod
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_superclass
|
17
|
+
assert_equal TestClass, @Class.superclass
|
18
|
+
assert @Instance.is_a? TestClass
|
19
|
+
assert @Instance.kind_of? TestClass
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require_relative "common.rb"
|
3
|
+
require_relative "../lib/partialclass.rb"
|
4
|
+
|
5
|
+
class InterfaceTests < Test::Unit::TestCase
|
6
|
+
def test_for_single
|
7
|
+
assert_respond_to Class, :<<
|
8
|
+
assert_respond_to TestClass, :<<
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_for_specialize
|
12
|
+
assert_respond_to Class, :specialize
|
13
|
+
assert_respond_to TestClass, :specialize
|
14
|
+
end
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: partialclass
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Simon Worthington
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-11-03 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.3'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.3'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description:
|
47
|
+
email:
|
48
|
+
- simon@simonwo.net
|
49
|
+
executables: []
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- .gitignore
|
54
|
+
- Gemfile
|
55
|
+
- LICENSE.txt
|
56
|
+
- README.md
|
57
|
+
- Rakefile
|
58
|
+
- lib/partialclass.rb
|
59
|
+
- lib/partialclass/version.rb
|
60
|
+
- partialclass.gemspec
|
61
|
+
- test/common.rb
|
62
|
+
- test/test_correctness.rb
|
63
|
+
- test/test_interface.rb
|
64
|
+
homepage: https://github.com/simonwo/partialclass
|
65
|
+
licenses:
|
66
|
+
- MIT
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options: []
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ! '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
requirements: []
|
84
|
+
rubyforge_project:
|
85
|
+
rubygems_version: 1.8.23
|
86
|
+
signing_key:
|
87
|
+
specification_version: 3
|
88
|
+
summary: Specialise a Ruby class by providing some of its initializer arguments or
|
89
|
+
attributes ahead of time.
|
90
|
+
test_files:
|
91
|
+
- test/common.rb
|
92
|
+
- test/test_correctness.rb
|
93
|
+
- test/test_interface.rb
|