interloper 0.1.2
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 +7 -0
- data/.gitignore +13 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/README.md +86 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/interloper.gemspec +27 -0
- data/lib/interloper/version.rb +3 -0
- data/lib/interloper.rb +105 -0
- metadata +110 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 018db11a5ba1cb6690bdda0ea60c640f3eda545f
|
4
|
+
data.tar.gz: bcc30391db7e438e9dee42bbf7b4ae5843d2fa9f
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e99ce01e495b431b015146efbe7781eb3ac6bd09cdf8befa76dc1905e2453d936102d660aa714017e10dd3d8a9a977d6e01f2ca378311798eed065e23bdefcc5
|
7
|
+
data.tar.gz: 210bc9f825f86b64b4ea2c9659672dca8e5bc24405a5c123d201683e55e7b1aab076ca306c806f364b760007da24247f41a3b63a4b26e964b7476e4df3ed8fc5
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
# Interloper
|
2
|
+
|
3
|
+
Interloper adds _before_ and _after_ callback hooks to methods on POROs (plain old Ruby objects).
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'interloper'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install interloper
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
To add `before` and `after` callbacks to a method:
|
24
|
+
```ruby
|
25
|
+
require 'interloper'
|
26
|
+
|
27
|
+
class Foo
|
28
|
+
include Interloper
|
29
|
+
|
30
|
+
before(:do_something) { puts "do something before" }
|
31
|
+
before(:do_something) { puts "do something else before" }
|
32
|
+
after(:do_something) { puts "do something after" }
|
33
|
+
after(:do_something) { puts "do something else after" }
|
34
|
+
|
35
|
+
def do_something
|
36
|
+
puts "doing it"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
Foo.new.do_something
|
41
|
+
```
|
42
|
+
**Output:**
|
43
|
+
```
|
44
|
+
do something before
|
45
|
+
do something else before
|
46
|
+
doing it
|
47
|
+
do something after
|
48
|
+
do something else after
|
49
|
+
=> nil
|
50
|
+
```
|
51
|
+
|
52
|
+
|
53
|
+
Callbacks will receive the same arguments as the method being called.
|
54
|
+
```ruby
|
55
|
+
require 'interloper'
|
56
|
+
class Foo
|
57
|
+
include Interloper
|
58
|
+
|
59
|
+
before(:do_something) do |x|
|
60
|
+
puts "do something before, with #{x}"
|
61
|
+
end
|
62
|
+
|
63
|
+
def do_something(something)
|
64
|
+
puts "doing it with #{something}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
Foo.new.do_something("grace and style")
|
69
|
+
```
|
70
|
+
Output:
|
71
|
+
```
|
72
|
+
do something before, with grace and style
|
73
|
+
doing it with grace and style
|
74
|
+
=> nil
|
75
|
+
```
|
76
|
+
|
77
|
+
## Development
|
78
|
+
|
79
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
80
|
+
|
81
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
82
|
+
|
83
|
+
## Contributing
|
84
|
+
|
85
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/Andrew Myers/interloper.
|
86
|
+
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "interloper"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/interloper.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'interloper/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "interloper"
|
8
|
+
spec.version = Interloper::VERSION
|
9
|
+
spec.authors = ["Andrew Myers"]
|
10
|
+
spec.email = ["afredmyers@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Add before and after hooks to PORO methods.}
|
13
|
+
spec.description = %q{Interloper adds before and after hooks to methods on plain old ruby objects.}
|
14
|
+
spec.homepage = "https://github.com/afred/interloper"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
17
|
+
f.match(%r{^(test|spec|features)/})
|
18
|
+
end
|
19
|
+
spec.bindir = "exe"
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.14"
|
24
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
25
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
26
|
+
spec.add_development_dependency "pry-byebug"
|
27
|
+
end
|
data/lib/interloper.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
require "interloper/version"
|
2
|
+
|
3
|
+
module Interloper
|
4
|
+
|
5
|
+
def interloper_module
|
6
|
+
self.class.interloper_module
|
7
|
+
end
|
8
|
+
|
9
|
+
def Interloper.included(base)
|
10
|
+
base.extend ClassMethods
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
|
15
|
+
# Generates an Interloper module that is namespeced under the including
|
16
|
+
# class, if one does not already exist. Then prepends the Interloper
|
17
|
+
# module to the including class.
|
18
|
+
# @return Module the Interloper module that was prepended to the including
|
19
|
+
# class.
|
20
|
+
def interloper_module
|
21
|
+
# Create the Interloper module if it doesn't exist already
|
22
|
+
const_set(:Interloper, generate_interloper_module) unless self.constants.include? :Interloper
|
23
|
+
# Prepend the interloper module
|
24
|
+
prepend const_get(:Interloper)
|
25
|
+
const_get(:Interloper)
|
26
|
+
end
|
27
|
+
|
28
|
+
def generate_interloper_module
|
29
|
+
Module.new do
|
30
|
+
class << self
|
31
|
+
# @return [Array] The list of available hooks.
|
32
|
+
def hooks
|
33
|
+
[:before, :after]
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [Hash] The default hash for tracking callbacks to methods.
|
37
|
+
def default_callbacks
|
38
|
+
{}.tap do |callbacks|
|
39
|
+
hooks.each do |hook|
|
40
|
+
callbacks[hook] = {}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# @param [Symbol] hook Optional name of a hook. See .hook method in
|
46
|
+
# this module.
|
47
|
+
# @param [Symbol] method_name Optional name of a method.
|
48
|
+
# @return [Hash, Array] A hash or array of callbacks. If the 'hook'
|
49
|
+
# param is provided, it will return a hash of callbacks keyed by
|
50
|
+
# method name. If both 'hook' and 'method_name' are provided, will
|
51
|
+
# return an array of callbacks for the given hook and method.
|
52
|
+
def callbacks(hook=nil, method_name=nil)
|
53
|
+
@callbacks ||= default_callbacks
|
54
|
+
if hook && method_name
|
55
|
+
# Returns callback stack for a given method and hook. If there
|
56
|
+
# aren't callbacks in the stack, return something enumberable to
|
57
|
+
# be loop-friendly.
|
58
|
+
@callbacks.fetch(hook).fetch(method_name, [])
|
59
|
+
elsif hook
|
60
|
+
# Return all callbacks for a given hook, e.g. :before.
|
61
|
+
@callbacks.fetch(hook)
|
62
|
+
else
|
63
|
+
@callbacks
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def run_callbacks(hook, method_name, object_context, *orig_args, &orig_block)
|
68
|
+
callbacks(hook, method_name).each do |callback|
|
69
|
+
object_context.instance_exec *orig_args, &callback
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def add_callbacks(hook, *method_names, &callback)
|
74
|
+
method_names.each do |method_name|
|
75
|
+
callbacks[hook][method_name] ||= []
|
76
|
+
callbacks[hook][method_name] << callback
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def define_interloper_methods(*method_names)
|
81
|
+
method_names.each do |method_name|
|
82
|
+
define_method(method_name) do |*args, &block|
|
83
|
+
called_method = __method__
|
84
|
+
interloper_module.run_callbacks(:before, called_method, self, *args, &block)
|
85
|
+
return_val = super(*args,&block)
|
86
|
+
interloper_module.run_callbacks(:after, called_method, self, *args, &block)
|
87
|
+
return_val
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def before(*method_names, &callback)
|
96
|
+
interloper_module.define_interloper_methods(*method_names)
|
97
|
+
interloper_module.add_callbacks(:before, *method_names, &callback)
|
98
|
+
end
|
99
|
+
|
100
|
+
def after(*method_names, &callback)
|
101
|
+
interloper_module.define_interloper_methods(*method_names)
|
102
|
+
interloper_module.add_callbacks(:after, *method_names, &callback)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
metadata
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: interloper
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Andrew Myers
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-10-21 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.14'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.14'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry-byebug
|
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
|
+
description: Interloper adds before and after hooks to methods on plain old ruby objects.
|
70
|
+
email:
|
71
|
+
- afredmyers@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".rspec"
|
78
|
+
- ".travis.yml"
|
79
|
+
- Gemfile
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- bin/console
|
83
|
+
- bin/setup
|
84
|
+
- interloper.gemspec
|
85
|
+
- lib/interloper.rb
|
86
|
+
- lib/interloper/version.rb
|
87
|
+
homepage: https://github.com/afred/interloper
|
88
|
+
licenses: []
|
89
|
+
metadata: {}
|
90
|
+
post_install_message:
|
91
|
+
rdoc_options: []
|
92
|
+
require_paths:
|
93
|
+
- lib
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ">="
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
requirements: []
|
105
|
+
rubyforge_project:
|
106
|
+
rubygems_version: 2.5.1
|
107
|
+
signing_key:
|
108
|
+
specification_version: 4
|
109
|
+
summary: Add before and after hooks to PORO methods.
|
110
|
+
test_files: []
|