copy_method 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 98ff0ac825441667e22d7fae9e1c7ecffbfbad5a
4
+ data.tar.gz: 6785fed9af3700378f57221c08627dae4bc7852a
5
+ SHA512:
6
+ metadata.gz: 2434af858357c0820e78fcb1b37b6c1fd9da8e8f3ef784a3f011d2bb59413e63a90bf0692b8a977b388a8398fc86b6dfad07220fd95220192f62db823d0f403b
7
+ data.tar.gz: 980c0465c9314ae0869060a9a4aab11ac964f56c1b5a2122b63becc351473c8d7d8b49040bd16906c2b5ed9e39fe005110173f4f139c811c9e1947b49df2ac77
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /spec/examples.txt
10
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,31 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.0
4
+ - 2.1.5
5
+ - ruby-head
6
+ - jruby-head
7
+ - rbx-2
8
+ jdk:
9
+ - openjdk7
10
+ - oraclejdk8
11
+ matrix:
12
+ exclude:
13
+ - rvm: 2.2.0
14
+ jdk: openjdk7
15
+ jdk: oraclejdk8
16
+ - rvm: 2.1.5
17
+ jdk: openjdk7
18
+ jdk: oraclejdk8
19
+ - rvm: 2.1.4
20
+ jdk: openjdk7
21
+ jdk: oraclejdk8
22
+ - rvm: ruby-head
23
+ jdk: openjdk7
24
+ jdk: oraclejdk8
25
+ - rvm: rbx-2
26
+ jdk: openjdk7
27
+ jdk: oraclejdk8
28
+ allow_failures:
29
+ - rvm: ruby-head
30
+ - rvm: jruby-head
31
+ before_install: gem install bundler -v 1.10.6
@@ -0,0 +1,13 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
+
5
+ We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
6
+
7
+ Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
+
9
+ Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
+
11
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
+
13
+ This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in copy_method.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Alexa Grey
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,122 @@
1
+ # CopyMethod [![Build Status](https://travis-ci.org/scryptmouse/copy_method.svg?branch=master)](https://travis-ci.org/scryptmouse/copy_method)
2
+
3
+ Here there be dragons.
4
+
5
+ This is an experiment in copying / moving methods between Ruby classes and modules. The idea is to ultimately
6
+ allow metaprogramming that works with something like Python's decorators, without excessive use of `alias_method`
7
+ and the like. In other words, preserving `super` / inheritance / method overriding.
8
+
9
+ It mostly works, though it's very, very experimental and has a few caveats. Methods created with `class_eval` or
10
+ `define_method` will _not_ work. It adds a generated helper module to the target class that will preserve
11
+ constant lookups, but obviously if the copied method calls any methods defined on the origin, it expects
12
+ those to exist on the target.
13
+
14
+ The method used here is different from delegation as it copies the _entire_ method to the target class or module,
15
+ any changes to the original method won't propagate (by design).
16
+
17
+ ## Installation
18
+
19
+ Add this line to your application's Gemfile:
20
+
21
+ ```ruby
22
+ gem 'copy_method'
23
+ ```
24
+
25
+ And then execute:
26
+
27
+ $ bundle
28
+
29
+ Or install it yourself as:
30
+
31
+ $ gem install copy_method
32
+
33
+ ## Usage
34
+
35
+ ```ruby
36
+ class Animal
37
+ def eat
38
+ end
39
+
40
+ def sleep
41
+ end
42
+
43
+ # It'll work with these types of class methods
44
+ def self.vertebrates
45
+ end
46
+
47
+ class << self
48
+ # Or these
49
+ def mammals
50
+ end
51
+ end
52
+ end
53
+
54
+ class Animal2
55
+ end
56
+
57
+ module Abilities
58
+ end
59
+
60
+ Animal.include Abilities
61
+
62
+ CopyMethod.copy :eat, from: Animal, to: Abilities
63
+ # `move` is shorthand for passing `remove: true` to `copy`
64
+ CopyMethod.move :sleep, from: Animal, to: Abilities
65
+
66
+ CopyMethod.copy_singleton :vertebrates, from: Animal, to: Animal2
67
+ ```
68
+
69
+ ### Note about singleton methods and modules
70
+
71
+ There's some special logic with copying singleton methods from a class to a module. In such a scenario,
72
+ unless specified otherwise, copying the method will place it in the target module's `instance_methods`,
73
+ so that any class that `extend`s it will be able to use those as class methods.
74
+
75
+ ```
76
+ module Scopes
77
+ end
78
+
79
+ Animal.extend Scopes
80
+
81
+ CopyMethod.move_singleton :vertebrates, from: Animal, to: Scopes
82
+
83
+ Animal.respond_to? :vertebrates # => true
84
+ Scopes.respond_to? :vertebrates # => false
85
+ Scopes.instance_method(:vertebrates) # => #<UnboundMethod: Scopes#vertebrates>
86
+ ```
87
+
88
+ If you want to actually copy it to the target module's `methods`, use the `singleton_target` option:
89
+
90
+ ```
91
+ CopyMethod.move_singleton :mammals, from: Animal, to: Scopes, singleton_target: true
92
+
93
+ Animal.respond_to? :mammals # => false
94
+ Scopes.respond_to? :mammals # => true
95
+ Scopes.method(:mammals) # => #<Method: Scopes.mammals>
96
+ ```
97
+
98
+ None of this applies when copying _to_ a class, _from_ a module, or between modules.
99
+
100
+ ### Why not just use modules?
101
+
102
+ Because this is an experiment for tinkering with some other metaprogramming projects. `Module.prepend` allows
103
+ for so many improved features, but there are still a few edge cases.
104
+
105
+ ## Development
106
+
107
+ ### TODO
108
+
109
+ * More tests
110
+ * Handle subclasses. If `Cat < Animal`, and we want to remove a method from `Cat` that is defined on `Animal`, specify the behavior.
111
+ * Add logic to ensure recopying a copied method will work (specifically the constants helper module)
112
+ * More tests
113
+ * More documentation
114
+ * More tests?
115
+
116
+ ## Contributing
117
+
118
+ Bug reports and pull requests are welcome on GitHub at ( https://github.com/scryptmouse/copy_method ). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
119
+
120
+ ## License
121
+
122
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,16 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require "yard"
4
+ require "yard/rake/yardoc_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec) do |t|
7
+ t.verbose = false
8
+ end
9
+
10
+ YARD::Rake::YardocTask.new do |t|
11
+ t.files = ['lib/**/*.rb', '-', 'README.md', 'LICENSE.txt', 'CODE_OF_CONDUCT.md']
12
+ t.options = ['--private', '--protected']
13
+ t.stats_options = ['--list-undoc']
14
+ end
15
+
16
+ task :default => :spec
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "pry"
5
+ require "copy_method"
6
+
7
+ Pry.start
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'copy_method/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "copy_method"
8
+ spec.version = CopyMethod::VERSION
9
+ spec.authors = ["Alexa Grey"]
10
+ spec.email = ["devel@mouse.vc"]
11
+
12
+ spec.summary = %q{Copy a method from one class to another (experimental)}
13
+ spec.description = %q{Copy a method from one class to another (experimental)}
14
+ spec.homepage = "https://github.com/scryptmouse/copy_method"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.required_ruby_version = '~> 2.1'
23
+
24
+ spec.add_dependency "method_source", ">= 0.8"
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.10"
27
+ spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "simplecov"
29
+ spec.add_development_dependency "rspec"
30
+ spec.add_development_dependency "yard"
31
+ spec.add_development_dependency "pry"
32
+ end
@@ -0,0 +1,77 @@
1
+ require "method_source"
2
+ require "copy_method/version"
3
+ require "copy_method/utils"
4
+ require "copy_method/method_copier"
5
+ require "copy_method/copied_method"
6
+ require "copy_method/integration"
7
+
8
+ module CopyMethod
9
+ module_function
10
+
11
+ # @param [Symbol] name
12
+ # @param [Class, Module] from
13
+ # @param [Class, Module] to
14
+ # @param [Boolean] singleton
15
+ # @param [Boolean] remove
16
+ # @param [Boolean] singleton_target
17
+ # @return [Symbol] the method name moved
18
+ def copy_method(name, from:, to:, **kwargs)
19
+ kwargs[:name] = name
20
+ kwargs[:from] = from
21
+ kwargs[:to] = to
22
+
23
+ copier = CopyMethod::MethodCopier.new **kwargs
24
+
25
+ copier.copy!
26
+ end
27
+
28
+ def move_method(name, **kwargs)
29
+ kwargs[:remove] = true
30
+
31
+ copy_method name, **kwargs
32
+ end
33
+
34
+ def copy_singleton_method(name, **kwargs)
35
+ kwargs[:singleton] = true
36
+
37
+ copy_method name, **kwargs
38
+ end
39
+
40
+ def move_singleton_method(name, **kwargs)
41
+ kwargs[:singleton] = true
42
+ kwargs[:remove] = true
43
+
44
+ copy_method name, **kwargs
45
+ end
46
+
47
+ class << self
48
+ alias copy copy_method
49
+ alias move move_method
50
+ alias copy_singleton copy_singleton_method
51
+ alias move_singleton move_singleton_method
52
+
53
+ def extend_object(base)
54
+ verb = case __method__
55
+ when :extend_object then 'extend'
56
+ when :append_features then 'include'
57
+ when :prepend_features then 'prepend'
58
+ # :nocov:
59
+ 'extend'
60
+ # :nocov:
61
+ end
62
+
63
+ $stderr.puts "Do not #{verb} CopyMethod directly. Use CopyMethod.patch! if you want methods in classes directly."
64
+ end
65
+
66
+ alias prepend_features extend_object
67
+ alias append_features extend_object
68
+
69
+ def patch!
70
+ Module.include CopyMethod::Integration
71
+ end
72
+ end
73
+ end
74
+
75
+ def CopyMethod(name, **kwargs)
76
+ CopyMethod.copy_method name, **kwargs
77
+ end
@@ -0,0 +1,49 @@
1
+ module CopyMethod
2
+ # Preserve constant lookups in copied methods.
3
+ class CopiedMethod < Module
4
+ # @!attribute [r] method_name
5
+ # @return [Symbol]
6
+ attr_reader :method_name
7
+
8
+ # @!attribute [r] origin
9
+ # @return [Symbol]
10
+ attr_reader :origin
11
+
12
+ attr_reader :singleton
13
+ alias singleton? singleton
14
+
15
+ # @param [Symbol] method_name
16
+ # @param [Class] origin
17
+ # @param [Boolean] singleton
18
+ def initialize(origin, method_name, singleton: false)
19
+ @method_name = method_name
20
+ @origin = origin.to_s.to_sym
21
+ @singleton = singleton
22
+
23
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
24
+ def const_missing(const_name)
25
+ caller_method = caller_locations(1,1)[0].label
26
+
27
+ super
28
+ rescue NameError => e
29
+ origin = ::#{origin}
30
+
31
+ if caller_method == #{method_name.to_s.inspect} && origin.const_defined?(const_name)
32
+ origin.const_get const_name
33
+ else
34
+ raise e
35
+ end
36
+ end
37
+ RUBY
38
+ end
39
+
40
+ def inspect
41
+ "CopyMethod::CopiedMethod(#{origin}#{method_symbol}#{method_name})"
42
+ end
43
+
44
+ private
45
+ def method_symbol
46
+ singleton? ? '.' : '#'
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,33 @@
1
+ module CopyMethod
2
+ module Integration
3
+ def copy_method(name, from: nil, to: nil, remove: false, singleton: false)
4
+ if from.nil? && to.nil?
5
+ raise ArgumentError, "must specify either `from` or `to` keywords"
6
+ end
7
+
8
+ from = self if from.nil?
9
+ to = self if to.nil?
10
+
11
+ CopyMethod.copy_method name, from: from, to: to, remove: remove, singleton: singleton
12
+ end
13
+
14
+ def move_method(name, **kwargs)
15
+ kwargs[:remove] = true
16
+
17
+ copy_method name **kwargs
18
+ end
19
+
20
+ def copy_singleton_method(name, **kwargs)
21
+ kwargs[:singleton] = true
22
+
23
+ copy_method name, **kwargs
24
+ end
25
+
26
+ def move_singleton_method(name, **kwargs)
27
+ kwargs[:singleton] = true
28
+ kwargs[:remove] = true
29
+
30
+ copy_method name, **kwargs
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,164 @@
1
+ module CopyMethod
2
+ # @api private
3
+ # @todo Be clever about `ActiveSupport::Concern`, if we are copying a singleton method
4
+ # to such a module, check for / create the `ClassMethods` submodule and place the
5
+ # method on that.
6
+ class MethodCopier
7
+ include CopyMethod::Utils
8
+
9
+ attr_reader :method_name, :from, :to, :singleton, :remove, :singleton_target
10
+
11
+ alias singleton_target? singleton_target
12
+ alias remove? remove
13
+ alias singleton? singleton
14
+ alias singleton_origin? singleton?
15
+
16
+ def initialize(name:, from:, to:, singleton: false, remove: false, singleton_target: nil)
17
+ @method_name = name
18
+ @from = assert_module! from, :from
19
+ @to = assert_module! to, :to
20
+ @singleton = singleton
21
+ @remove = remove
22
+
23
+ if singleton_target.nil?
24
+ @singleton_target = to_module? ? false : singleton
25
+ else
26
+ @singleton_target = !!singleton_target
27
+ end
28
+ end
29
+
30
+ def definition
31
+ @_definition ||= fetch_method_definition
32
+ end
33
+
34
+ # Wrapper around {#from}
35
+ def origin
36
+ from
37
+ end
38
+
39
+ # Wrapper around {#to}.
40
+ #
41
+ # If copying a singleton method, the possibility that it has a
42
+ # {#singleton_receiver} in its method body needs to be accounted for.
43
+ #
44
+ # @return [Class]
45
+ def target
46
+ if singleton_target?
47
+ singleton_receiver? ? to : to.singleton_class
48
+ else
49
+ to
50
+ end
51
+ end
52
+
53
+ # Where the magic happens.
54
+ #
55
+ # @return [Symbol]
56
+ def copy!
57
+ location, line = definition.source_location
58
+
59
+ target.module_eval corrected_source, location, line
60
+
61
+ attach_helper_module!
62
+
63
+ remove_from_origin! if remove?
64
+
65
+ return method_name
66
+ end
67
+
68
+ # @return [String]
69
+ def method_source
70
+ definition.source
71
+ end
72
+
73
+ # Populated with the `receiver` for defining singleton methods.
74
+ #
75
+ # In the method source, this would be something that looks like
76
+ # `def self.foo` where `foo` is the method name, and `self` is
77
+ # the receiver.
78
+ #
79
+ # Since we're copying with source, the presence of this determines
80
+ # _where_ to define the new method on the target.
81
+ def singleton_receiver
82
+ @_singleton_receiver ||= singleton? ? ( method_source[receiver_rgx, 2] || '' ) : ''
83
+ end
84
+
85
+ def singleton_receiver?
86
+ !singleton_receiver.empty?
87
+ end
88
+
89
+ def class_receiver?
90
+ singleton_receiver? && singleton_receiver != 'self'
91
+ end
92
+
93
+ # @return [String]
94
+ def corrected_source
95
+ correct_source_receiver method_source
96
+ end
97
+
98
+ def from_module?
99
+ looks_like_module? from
100
+ end
101
+
102
+ def to_module?
103
+ looks_like_module? to
104
+ end
105
+
106
+ # This checks for the condition where we want to copy a `Class`'s
107
+ # singleton method to a `Module`'s instance methods. By default,
108
+ # the library assumes that you would want to copy a method for any
109
+ # `Class` that then extends the target module.
110
+ #
111
+ # To override this logic, explicitly set `{#singleton_target}` to
112
+ # `true` if providing a module to `{#to}`.
113
+ #
114
+ def convert_to_instance_method?
115
+ singleton? && to_module? && !from_module? && !singleton_target?
116
+ end
117
+
118
+ private
119
+ # This generates a {CopyMethod::CopiedMethod} module instance that
120
+ # will preserve any constant accesses that were defined in the
121
+ # {#origin}, but do not exist in the {#target}
122
+ #
123
+ # @return [void]
124
+ def attach_helper_module!
125
+ helper_mod = CopyMethod::CopiedMethod.new origin, method_name, singleton: singleton_origin?
126
+
127
+ to.extend helper_mod
128
+ end
129
+
130
+ # @return [String]
131
+ def correct_source_receiver(source)
132
+ if convert_to_instance_method?
133
+ source.sub receiver_rgx, '\1 \3'
134
+ elsif singleton? && class_receiver?
135
+ source.sub receiver_rgx, '\1self.\3'
136
+ else
137
+ source
138
+ end
139
+ end
140
+
141
+ # @return [Regexp]
142
+ def receiver_rgx
143
+ /(def\s+)([^\.\s]+)\.(#{definition.name})\b/
144
+ end
145
+
146
+ # @return [void]
147
+ def remove_from_origin!
148
+ if singleton_origin?
149
+ origin.singleton_class.__send__ :remove_method, method_name
150
+ else
151
+ origin.__send__ :remove_method, method_name
152
+ end
153
+ end
154
+
155
+ # @return [UnboundMethod, Method]
156
+ def fetch_method_definition
157
+ if singleton_origin?
158
+ origin.method method_name
159
+ else
160
+ origin.instance_method method_name
161
+ end
162
+ end
163
+ end
164
+ end
@@ -0,0 +1,26 @@
1
+ module CopyMethod
2
+ module Utils
3
+ module_function
4
+
5
+ # @param [Module, Object] object
6
+ def looks_like_module?(object)
7
+ object.is_a?(::Module) && ( object.class == ::Module || object.ancestors.include?(Module) )
8
+ end
9
+
10
+ # @param [Module, Class] thing
11
+ # @param [Symbol] parameter_name
12
+ # @raise [ArgumentError] if thing is not a module
13
+ # @return [Module, Class]
14
+ def assert_module!(thing, parameter_name = :thing)
15
+ raise TypeError, "#{parameter_name}: #{thing.inspect} is not a `Module`" unless thing.is_a?(Module)
16
+
17
+ return thing
18
+ end
19
+
20
+ def activesupport_concern?(thing)
21
+ return false unless defined?(ActiveSupport::Concern)
22
+
23
+ looks_like_module?(thing) && thing.kind_of?(ActiveSupport::Concern)
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,3 @@
1
+ module CopyMethod
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,159 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: copy_method
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Alexa Grey
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-09-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: method_source
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0.8'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.10'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.10'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: yard
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: pry
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: Copy a method from one class to another (experimental)
112
+ email:
113
+ - devel@mouse.vc
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - ".gitignore"
119
+ - ".rspec"
120
+ - ".travis.yml"
121
+ - CODE_OF_CONDUCT.md
122
+ - Gemfile
123
+ - LICENSE.txt
124
+ - README.md
125
+ - Rakefile
126
+ - bin/console
127
+ - copy_method.gemspec
128
+ - lib/copy_method.rb
129
+ - lib/copy_method/copied_method.rb
130
+ - lib/copy_method/integration.rb
131
+ - lib/copy_method/method_copier.rb
132
+ - lib/copy_method/utils.rb
133
+ - lib/copy_method/version.rb
134
+ homepage: https://github.com/scryptmouse/copy_method
135
+ licenses:
136
+ - MIT
137
+ metadata: {}
138
+ post_install_message:
139
+ rdoc_options: []
140
+ require_paths:
141
+ - lib
142
+ required_ruby_version: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - "~>"
145
+ - !ruby/object:Gem::Version
146
+ version: '2.1'
147
+ required_rubygems_version: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ requirements: []
153
+ rubyforge_project:
154
+ rubygems_version: 2.4.5
155
+ signing_key:
156
+ specification_version: 4
157
+ summary: Copy a method from one class to another (experimental)
158
+ test_files: []
159
+ has_rdoc: