synecdoche 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/LICENSE +24 -0
- data/README.md +109 -0
- data/Rakefile +18 -0
- data/examples/partial_class.rb +11 -0
- data/examples/some_class.rb +5 -0
- data/lib/partial_class/partial_class.rb +33 -0
- data/lib/source_parser/source_parser.rb +38 -0
- data/lib/synecdoche.rb +5 -0
- data/lib/version/version.rb +9 -0
- metadata +55 -0
data/LICENSE
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
Copyright (c) 2012 Dan Swain
|
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.
|
23
|
+
|
24
|
+
|
data/README.md
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
# Synecdoche
|
2
|
+
|
3
|
+
Synecdoche:
|
4
|
+
>_a figure of speech by which a part is put for the
|
5
|
+
>whole (as fifty sail for fifty ships), the whole for a part (as
|
6
|
+
>society for high society), the species for the genus (as cutthroat for
|
7
|
+
>assassin), the genus for the species (as a creature for a man), or the
|
8
|
+
>name of the material for the thing made (as boards for stage)_
|
9
|
+
>[m-w.com](http://www.merriam-webster.com/dictionary/synecdoche)
|
10
|
+
|
11
|
+
Synecdoche is a Ruby gem that enables you to include parts of a file,
|
12
|
+
class, or module. It is useful for testing specific methods that can
|
13
|
+
stand alone but are part of a larger module that has potentially
|
14
|
+
complex dependencies.
|
15
|
+
|
16
|
+
In some sense, Synecdoche solves a problem that shouldn't exist. Your
|
17
|
+
code _should_ be written so that each logical piece of code is
|
18
|
+
testable on its own. However, in the real world, you sometimes have
|
19
|
+
to work with code involving large modules with complex dependencies.
|
20
|
+
|
21
|
+
Synecdoche is a tool that you can use to refactor complex code. It
|
22
|
+
allows you to test the parts of the code that you want to refactor
|
23
|
+
while they are still embedded in larger modules. Then, once you have
|
24
|
+
tests, you can refactor with confidence, and eventually you won't
|
25
|
+
need Synecdoche anymore.
|
26
|
+
|
27
|
+
## License
|
28
|
+
|
29
|
+
Synecdoche is released under the
|
30
|
+
[MIT license](http://en.wikipedia.org/wiki/MIT_License).
|
31
|
+
See the LICENSE file.
|
32
|
+
|
33
|
+
## Requirements
|
34
|
+
|
35
|
+
Synecdoche should work on any Ruby. It's only been tested on Ruby
|
36
|
+
1.9.3 so far, though.
|
37
|
+
|
38
|
+
## Installation
|
39
|
+
|
40
|
+
_Note: The gem hasn't been published yet and I haven't added the
|
41
|
+
Rakefile yet. These tasks will be done soon._
|
42
|
+
|
43
|
+
If your system is set up to allow it, you can just do
|
44
|
+
|
45
|
+
gem install synecdoche
|
46
|
+
|
47
|
+
Or, if you prefer a more hands-on approach or want to hack at the source:
|
48
|
+
|
49
|
+
git clone git://github.com/simplifi/synecdoche.git
|
50
|
+
cd synecdoche
|
51
|
+
rake install
|
52
|
+
|
53
|
+
If you are working on a system where you need to `sudo gem install`
|
54
|
+
you can do
|
55
|
+
|
56
|
+
rake gem
|
57
|
+
sudo gem install synecdoche
|
58
|
+
|
59
|
+
As always, you can `rake -T` to find out what other rake tasks we have
|
60
|
+
provided.
|
61
|
+
|
62
|
+
## Basic Usage
|
63
|
+
|
64
|
+
Suppose we have a class `SomeClass` defined in `some_class.rb`:
|
65
|
+
|
66
|
+
# some_class.rb
|
67
|
+
|
68
|
+
# potentially lots of dependencies here
|
69
|
+
|
70
|
+
class SomeClass
|
71
|
+
# other methods, etc...
|
72
|
+
|
73
|
+
# a method we'd like to refactor
|
74
|
+
def double x
|
75
|
+
2*x
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
Using Synecdoche, we could extract `SomeClass#double` into a smaller
|
81
|
+
class without needing to import all of `some_class.rb`:
|
82
|
+
|
83
|
+
# spec/test_double_method.rb
|
84
|
+
|
85
|
+
require 'synecdoche'
|
86
|
+
|
87
|
+
class PartialSomeClass < Synecdoche::PartialClass
|
88
|
+
include_method :double
|
89
|
+
end
|
90
|
+
|
91
|
+
If the directories are set up right, Synecdoche will guess the file
|
92
|
+
name (using Rails' camel casing guidelines) of the source file.
|
93
|
+
Otherwise we could do `include_method :double, :file_name =>
|
94
|
+
"path/to/some_class.rb"`.
|
95
|
+
|
96
|
+
More docs coming soon.
|
97
|
+
|
98
|
+
## Contributing
|
99
|
+
|
100
|
+
The usual github process applies here:
|
101
|
+
|
102
|
+
1. Fork it
|
103
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
104
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
105
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
106
|
+
5. Create new Pull Request
|
107
|
+
|
108
|
+
You can also contribute to the author's ego by letting him know that
|
109
|
+
you find String Eater useful ;)
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'rake/clean'
|
2
|
+
|
3
|
+
project_name = "synecdoche"
|
4
|
+
|
5
|
+
desc "Run rspec spec/ (compile if needed)"
|
6
|
+
task :test do
|
7
|
+
sh "rspec spec/"
|
8
|
+
end
|
9
|
+
|
10
|
+
desc "Create gem"
|
11
|
+
task :gem => "#{project_name}.gemspec" do
|
12
|
+
sh "gem build #{project_name}.gemspec"
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Install using 'gem install'"
|
16
|
+
task :install => :gem do
|
17
|
+
sh "gem install #{project_name}"
|
18
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Synecdoche
|
2
|
+
class PartialClass
|
3
|
+
def self.parser
|
4
|
+
@parser ||= Synecdoche::SourceParser.new
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.from_file file_name
|
8
|
+
@file_name = file_name
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.part_of class_name
|
12
|
+
@class_name = class_name
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.class_name
|
16
|
+
@class_name ||= name.gsub(/\APartial/, '')
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.file_name
|
20
|
+
@file_name ||= (Synecdoche::SourceParser::underscore(class_name) + ".rb")
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.include_method name, opts={}
|
24
|
+
from_file(opts[:file_name]) if opts[:file_name]
|
25
|
+
part_of(opts[:class_name]) if opts[:class_name]
|
26
|
+
|
27
|
+
parser.ensure_parsed(file_name)
|
28
|
+
source = parser.method_source_in_class(name, class_name)
|
29
|
+
|
30
|
+
class_eval(source)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'rdoc'
|
2
|
+
require 'rdoc/rdoc'
|
3
|
+
|
4
|
+
module Synecdoche
|
5
|
+
class SourceParser
|
6
|
+
def self.underscore string
|
7
|
+
string.gsub(/::/, '/').
|
8
|
+
gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
|
9
|
+
gsub(/([a-z\d])([A-Z])/,'\1_\2').
|
10
|
+
tr("-", "_").
|
11
|
+
downcase
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@rdoc = RDoc::RDoc.new
|
16
|
+
@rdoc.options = RDoc::Options.new
|
17
|
+
end
|
18
|
+
|
19
|
+
def parse_file file_name
|
20
|
+
@file_name = file_name
|
21
|
+
@file = @rdoc.parse_files([file_name]).first
|
22
|
+
end
|
23
|
+
|
24
|
+
def ensure_parsed file_name
|
25
|
+
unless @file && (@file_name == file_name)
|
26
|
+
parse_file(file_name)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def method_source_in_class method_name, class_name
|
31
|
+
raise "No file parsed" unless @file
|
32
|
+
klass = @file.classes.find{|c| c.name == class_name.to_s}
|
33
|
+
klass.method_list.find do |m|
|
34
|
+
m.name == method_name.to_s
|
35
|
+
end.tokens_to_s
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/synecdoche.rb
ADDED
metadata
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: synecdoche
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Dan Swain
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-08-24 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Include parts of a class in another class.
|
15
|
+
email:
|
16
|
+
- dan@simpli.fi
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- lib/synecdoche.rb
|
22
|
+
- lib/partial_class/partial_class.rb
|
23
|
+
- lib/source_parser/source_parser.rb
|
24
|
+
- lib/version/version.rb
|
25
|
+
- examples/partial_class.rb
|
26
|
+
- examples/some_class.rb
|
27
|
+
- LICENSE
|
28
|
+
- Rakefile
|
29
|
+
- README.md
|
30
|
+
homepage: http://github.com/simplifi/synecdoche
|
31
|
+
licenses: []
|
32
|
+
post_install_message:
|
33
|
+
rdoc_options: []
|
34
|
+
require_paths:
|
35
|
+
- lib
|
36
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ! '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
|
+
none: false
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
requirements: []
|
49
|
+
rubyforge_project:
|
50
|
+
rubygems_version: 1.8.24
|
51
|
+
signing_key:
|
52
|
+
specification_version: 3
|
53
|
+
summary: Include parts of a class in another class. Useful for refactoring large
|
54
|
+
modules with complex dependencies.
|
55
|
+
test_files: []
|