prong 1.0.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: 61273b7963ed12684e1d5133e1f95e318a2f4c06
4
+ data.tar.gz: a6cfd1e30e15377e46c0d4dfe9e96c2afe8da5af
5
+ SHA512:
6
+ metadata.gz: 9951ea5ccd25b3dd73a7a4c1f9547388f990f8d694219602d7eb35ec9bc89dddbd2a570984ea449fbf07a82c7dccfbd6a81c34277d331d93764f13a9365836ee
7
+ data.tar.gz: 6c119e8203b6626a02244f816246a580d0091e064e10772a8a3120c4f7fec926f134f89ae20bfbaef2a70a860f6dce245f72e3ba315efc63ef889e09e835d039
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2.3
4
+ 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,5 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'activesupport'
4
+ # Specify your gem's dependencies in prong.gemspec
5
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 TODO: Write your name
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,170 @@
1
+ # Prong
2
+ Activesupport-like callbacks but upto %20 faster.
3
+
4
+ # Introduction
5
+
6
+ Prong is almost behave like ActiveSupport::Callbakcs in most of the cases. It's let you define hooks, add callbacks to them, and conditionally run them whenever you want. Prong is not just another one, It's faster! It's independent! Also there's some differences.
7
+
8
+ There are some functionalities like `reset_callbacks`,`scope` which unfortunately not supported in version 1.0.0.
9
+ I'll add those functionalities in next version.
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem 'prong', '~> 1.0'
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ $ bundle
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install prong
26
+
27
+ ## Usage
28
+
29
+ Let's start with an Account:
30
+
31
+ ```ruby
32
+ class Account
33
+ include Prong
34
+ attr_accessor :password_salt
35
+ define_hook :save
36
+
37
+ before_save proc { self.password_salt = Random.srand unless self.password_salt }, :valid?
38
+ after_save :notify, if: proc { saved? }
39
+
40
+ def valid?
41
+ raise unless self.password_salt
42
+ end
43
+
44
+ def saved?
45
+ # Must return boolean
46
+ true
47
+ end
48
+
49
+ def notify
50
+ # Send Async notification to account owner
51
+ end
52
+
53
+ def save
54
+ run_hooks!(:save)
55
+ end
56
+ end
57
+ ```
58
+ Lets's save account and see what's going to happen
59
+ ```ruby
60
+ account = Account.new
61
+ account.password_salt.nil?
62
+ # => true
63
+ account.save
64
+ # => true
65
+ account.password_salt.nil?
66
+ # => false
67
+ ```
68
+ ### Class Methods
69
+ #### define_hook
70
+ You can define multiple hooks at once with `#define_hook`, each argument defines three hooks on context class `before_*`, `around_*`, `after_*`.`#define_hook` takes multiple `Symbol` argument.
71
+
72
+ ```ruby
73
+ class Account
74
+ include Prong
75
+ define_hook :save, :update
76
+ # hooks
77
+ # before_save, around_save, after_save, before_update, around_update, after_update
78
+ end
79
+ ```
80
+ A hook accept multiple arguments(Proc, Symbol), hook consider last argument as a condition if argument is kind of `Hash` with `if` key. Prong doesn't support `unless` condition like `ActiveSupport::Callbacks` because it's unnecessary.
81
+ Condition type must be `proc`! `lambda` doesn't supported.
82
+
83
+ ```ruby
84
+ class Account
85
+ include Prong
86
+ define_hook :update
87
+ # Below hook will be executed if condition return true.
88
+ before_update :authorized?, proc { self.updated_at = Time.now }, if: proc { self.changed? }
89
+ end
90
+ ```
91
+ ### skip_hook
92
+ You can skip callbacks in context class or sub classes of context:
93
+ ```ruby
94
+ class Account
95
+ include Prong
96
+ define_hook :save
97
+ around_save :log
98
+ after_save :notify, :notify_to_admin
99
+ end
100
+
101
+ class X < Account
102
+ skip_hook :save, :after, :notify, :notify_to_admin
103
+ skip_hook :save, :around, :log, if: proc { self.log? }
104
+ end
105
+ ```
106
+ `#skip_hook` accept condition too.
107
+
108
+ ### skip_all_hooks
109
+ You can skip all callbacks in hook with `#skip_all_hooks`
110
+ ```ruby
111
+ class Account
112
+ include Prong
113
+ define_hook :save
114
+ around_save :log
115
+ after_save :notify, :notify_to_admin
116
+ end
117
+
118
+ class X < Account
119
+ skip_all_hooks :save, :after
120
+ skip_all_hooks :save, :around, if: proc { self.skip? }
121
+ end
122
+ ```
123
+ `#skip_all_hooks` accept condition too.
124
+
125
+ ## Instance Methods
126
+ ### run_hooks
127
+ `#run_hooks` run callbacks with halting feature, it means if one of the callbacks returned `false`, callback chain will be halted.
128
+
129
+ `#run_hooks` takes four arguments which three of them are optional.
130
+
131
+ First argument is name of the hook you want to run and it's required,
132
+
133
+ The second argument is type of the hook, It's accept these arguments `:before, :around, :after, :all`. Default value is `:all`.
134
+
135
+ The third argument determines return value, if you set it to `true` return value will be array of values which returned from callbacks + value which returned from the forth argument. if you set it to `false` return value will be the value which evaluated from the forth argument.
136
+
137
+ The Forth argument is a block, which will be executed in middle of `around` hook. You can consider it as a return value of `#run_hooks`.
138
+ As i said forth argument is optional, if you don't pass a block to `#run_hooks` return value will be `true` if callback chain doesn't halted.
139
+
140
+ ```ruby
141
+ class Account
142
+ include Prong
143
+ define_hook :update
144
+ before_update :authroized?
145
+ def update
146
+ run_hooks(:update, :all, false) do
147
+ # Do update business here
148
+ # return value is a value which evaluated from this block
149
+ end
150
+ end
151
+ end
152
+
153
+ account = Account.new
154
+ account.run_hooks(:update, :all, true) do
155
+ # Do update business here
156
+ # return value will be Array of values which returned from callbacks + value which returned from this block
157
+ end
158
+ ```
159
+
160
+ ### run_hooks!
161
+ The only difference between `#run_hooks!` and `#run_hooks` is `#run_hooks!` doesn't support halting feature.
162
+
163
+ ## Contributing
164
+
165
+ Bug reports and pull requests are welcome on GitHub at https://github.com/EhsanYousefi/prong. 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.
166
+
167
+
168
+ ## License
169
+
170
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "prong"
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
@@ -0,0 +1,7 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+
5
+ bundle install
6
+
7
+ # Do any other automated setup that you need to do here
Binary file
@@ -0,0 +1,16 @@
1
+ require "prong/version"
2
+ require "prong/hooks/define"
3
+ require "prong/hooks/skip"
4
+ require "prong/hooks/skip_all"
5
+ require "prong/hooks/executer"
6
+ require "prong/class_methods"
7
+ require "prong/instance_methods"
8
+ require "prong/class_attr"
9
+
10
+ module Prong
11
+ def self.included(host)
12
+ host.extend(ClassAttr)
13
+ host.extend(ClassMethods)
14
+ host.include(InstanceMethods)
15
+ end
16
+ end
Binary file
@@ -0,0 +1,10 @@
1
+ module Prong
2
+ module ClassAttr
3
+ def class_attr(*args)
4
+ args.each do |arg|
5
+ define_singleton_method(arg) { [] }
6
+ define_singleton_method("#{arg}=") { |param| define_singleton_method(arg) { param } }
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,17 @@
1
+ module Prong
2
+ module ClassMethods
3
+ def define_hook(*args)
4
+ args.each do |arg|
5
+ Hooks::Define.construct(self,arg)
6
+ end
7
+ end
8
+
9
+ def skip_hook(name,type,*args)
10
+ Hooks::Skip.construct(self,name,type,args)
11
+ end
12
+
13
+ def skip_all_hooks(name,type,condition={})
14
+ Hooks::SkipAll.construct(self,name,type,condition[:if])
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,64 @@
1
+ module Prong
2
+ module Hooks
3
+ class Chain
4
+ def initialize(base, name)
5
+ @base = base
6
+ @name = name
7
+ end
8
+
9
+ def prepare
10
+ all; before; after; around; return self
11
+ end
12
+
13
+ def compile(block, type)
14
+ callbacks = instance_variable_get("@#{type}")
15
+ callbacks[0][callbacks[1]] = [block,[]]
16
+ return callbacks[0]
17
+ end
18
+
19
+ private
20
+ def all
21
+ @all = [([] + get_before + get_around + ['_***_'] + get_around + get_after)]
22
+ @all << @all[0].index('_***_')
23
+ end
24
+
25
+ def before
26
+ @before = [([] + get_before + ['_***_'])]
27
+ @before << @before[0].index('_***_')
28
+ end
29
+
30
+ def after
31
+ @after = [(['_***_'] + get_after)]
32
+ @after << @after[0].index('_***_')
33
+ end
34
+
35
+ def around
36
+ @around = [(get_around + ['_***_'] + get_around)]
37
+ @around << @around[0].index('_***_')
38
+ end
39
+
40
+ def get_before
41
+ @get_before ||= deep_dup(@base.send("_before_#{@name}"))
42
+ end
43
+
44
+ def get_around
45
+ @get_around ||= deep_dup(@base.send("_around_#{@name}"))
46
+ end
47
+
48
+ def get_after
49
+ @get_after ||= deep_dup(@base.send("_after_#{@name}"))
50
+ end
51
+
52
+ def deep_dup(array)
53
+ array.map do |it|
54
+ if it.class == Array
55
+ # recursive method call instead of while loop
56
+ next deep_dup(it.dup)
57
+ else
58
+ next it
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,45 @@
1
+ require_relative 'chain'
2
+ module Prong
3
+ module Hooks
4
+ class Define
5
+ def self.construct(base,arg)
6
+ self.new(base,arg).handle
7
+ end
8
+
9
+ def initialize(base,name)
10
+ @base = base
11
+ @name = name
12
+ end
13
+
14
+ def handle
15
+ callback_attrs
16
+ define_callbacks_chain
17
+ define_callbacks
18
+ end
19
+
20
+ private
21
+ def callback_attrs
22
+ @callback_attrs ||= @base.class_attr("_before_#{@name}", "_around_#{@name}", "_after_#{@name}")
23
+ end
24
+
25
+ def define_callbacks_chain
26
+ @base.class_attr("_#{@name}_callbacks")
27
+ @base.send("_#{@name}_callbacks=", Chain.new(@base, @name).prepare)
28
+ end
29
+
30
+ def define_callbacks
31
+ callback_attrs.each do |attribute|
32
+ name = @name
33
+ @base.class_eval do
34
+ define_singleton_method(attribute[1..-1]) do |*args, &block|
35
+ condition = (args.pop if args.last.kind_of?(Hash)) || {}
36
+ args << block if block
37
+ self.send("#{attribute}=", self.send("#{attribute}") << [[condition[:if]].compact, args])
38
+ self.send("_#{name}_callbacks=", Chain.new(self, name).prepare)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,83 @@
1
+ module Prong
2
+ module Hooks
3
+ module Executer
4
+ module Falsey
5
+ def self.with_return_all(obj,name,type,&block)
6
+ return_block = nil
7
+ return_collection = []
8
+ closure = Proc.new { return_block ||= block.call if block }
9
+ callbacks = obj.class.send("_#{name}_callbacks")
10
+ callbacks.compile([closure],type).each do |callback|
11
+ callback[0].each { |b| next callback[1].clear unless obj.instance_exec(callback[1], &b) }
12
+ return_collection << callback[1].map do |i|
13
+ case i
14
+ when Symbol
15
+ if (o = obj.send(i)) == false
16
+ return false
17
+ else
18
+ next o
19
+ end
20
+ when Proc
21
+ if (o = obj.instance_exec(&i)) == false
22
+ return false
23
+ else
24
+ next o
25
+ end
26
+ end
27
+ end
28
+ end
29
+ return [return_collection.flatten].push([return_block||true].flatten)
30
+ end
31
+
32
+ def self.without_return_all(obj,name,type,&block)
33
+ return_block = nil
34
+ closure = Proc.new { return_block ||= block.call if block }
35
+ callbacks = obj.class.send("_#{name}_callbacks")
36
+ callbacks.compile([closure],type).each do |callback|
37
+ callback[0].each { |b| next callback[1].clear unless obj.instance_exec(callback[1], &b) }
38
+ callback[1].each do |i|
39
+ case i
40
+ when Symbol
41
+ if obj.send(i) == false
42
+ return false
43
+ else
44
+ next
45
+ end
46
+ when Proc
47
+ if obj.instance_exec(&i) == false
48
+ return false
49
+ else
50
+ next
51
+ end
52
+ end
53
+ end
54
+ end
55
+ return return_block || true
56
+ end
57
+ end
58
+
59
+ def self.with_return_all(obj,name,type,&block)
60
+ return_block = nil
61
+ return_collection = []
62
+ closure = Proc.new { return_block ||= block.call if block }
63
+ callbacks = obj.class.send("_#{name}_callbacks")
64
+ callbacks.compile([closure],type).each do |callback|
65
+ callback[0].each { |b| next callback[1].clear unless obj.instance_exec(callback[1], &b) }
66
+ return_collection << callback[1].map { |i| case i when Symbol then next obj.send(i) when Proc then next obj.instance_exec(&i) end }
67
+ end
68
+ return [return_collection.flatten].push([return_block||true].flatten)
69
+ end
70
+
71
+ def self.without_return_all(obj,name,type,&block)
72
+ return_block = nil
73
+ closure = Proc.new { return_block ||= block.call if block }
74
+ callbacks = obj.class.send("_#{name}_callbacks")
75
+ callbacks.compile([closure],type).each do |callback|
76
+ callback[0].each { |b| next callback[1].clear unless obj.instance_exec(callback[1], &b) }
77
+ callback[1].each { |i| case i when Symbol then next obj.send(i) when Proc then next obj.instance_exec(&i) end }
78
+ end
79
+ return return_block || true
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,59 @@
1
+ module Prong
2
+ module Hooks
3
+ class Skip
4
+ def self.construct(base,name,type,list)
5
+ self.new(base,name,type,list).handle
6
+ end
7
+
8
+ def initialize(base,name,type,list)
9
+ @base = base; @name = name
10
+ @type = type; @list = list
11
+ @condition = (@list.pop[:if] if @list.last.kind_of?(Hash))
12
+ end
13
+
14
+ def handle
15
+ if @condition
16
+ exclude_with_condition
17
+ else
18
+ exclude_without_condition
19
+ end
20
+ end
21
+
22
+ private
23
+ def callbacks
24
+ @callbacks ||= @base.send("_#{@type}_#{@name}")
25
+ end
26
+
27
+ def exclude_with_condition
28
+ condition = @condition; list = @list;
29
+ modifer = callbacks.map do |callback|
30
+ block = proc do |c|
31
+ list.each {|i| c.delete(i)} if instance_exec(&condition)
32
+ next true
33
+ end
34
+ callback[0] << block
35
+ callback
36
+ end
37
+ modify(modifer)
38
+ end
39
+
40
+ def exclude_without_condition
41
+ list = @list
42
+ modifer = callbacks.map do |callback|
43
+ block = proc do |c|
44
+ list.each {|i| c.delete(i)}
45
+ next true
46
+ end
47
+ callback[0] << block
48
+ callback
49
+ end
50
+ modify(modifer)
51
+ end
52
+
53
+ def modify(modifer)
54
+ @base.send("_#{@type}_#{@name}=", modifer)
55
+ @base.send("_#{@name}_callbacks=", Chain.new(@base, @name).prepare)
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,57 @@
1
+ module Prong
2
+ module Hooks
3
+ class SkipAll
4
+ def self.construct(base,name,type,condition)
5
+ self.new(base,name,type,condition).handle
6
+ end
7
+
8
+ def initialize(base,name,type,condition)
9
+ @base = base; @name = name
10
+ @type = type; @condition = condition
11
+ end
12
+
13
+ def handle
14
+ if @condition
15
+ exclude_all_with_condition
16
+ else
17
+ exclude_all_without_condition
18
+ end
19
+ end
20
+
21
+ private
22
+ def callbacks
23
+ @callbacks ||= @base.send("_#{@type}_#{@name}")
24
+ end
25
+
26
+ def exclude_all_without_condition
27
+ modifier = callbacks.map do |callback|
28
+ block = proc do |c|
29
+ c.clear
30
+ next true
31
+ end
32
+ callback[0] << block
33
+ callback
34
+ end
35
+ modify(modifier)
36
+ end
37
+
38
+ def exclude_all_with_condition
39
+ condition = @condition
40
+ modifier = callbacks.map do |callback|
41
+ block = proc do |c|
42
+ c.clear if instance_exec(&condition)
43
+ next true
44
+ end
45
+ callback[0] << block
46
+ callback
47
+ end
48
+ modify(modifier)
49
+ end
50
+
51
+ def modify(modifier)
52
+ @base.send("_#{@type}_#{@name}=", modifier)
53
+ @base.send("_#{@name}_callbacks=", Chain.new(@base, @name).prepare)
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,13 @@
1
+ module Prong
2
+ module InstanceMethods
3
+ def run_hooks(name,type = 'all', return_all = false, &block)
4
+ return Hooks::Executer::Falsey.without_return_all(self,name,type,&block) unless return_all
5
+ return Hooks::Executer::Falsey.with_return_all(self,name,type,&block)
6
+ end
7
+
8
+ def run_hooks!(name,type = 'all', return_all = false, &block)
9
+ return Hooks::Executer.without_return_all(self,name,type,&block) unless return_all
10
+ return Hooks::Executer.with_return_all(self,name,type,&block)
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module Prong
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'prong/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "prong"
8
+ spec.version = Prong::VERSION
9
+ spec.authors = ["Ehsan Yousefi"]
10
+ spec.email = ["ehsan.yousefi@live.com"]
11
+
12
+ spec.summary = %q{Activesupport-like callbacks but upto %20 faster.}
13
+ spec.description = %q{Prong is almost behave like ActiveSupport::Callbakcs in most of the cases. It's let you define hooks, add callbacks to them, and conditionally run them whenever you want. Prong is not just another one, It's faster! It's independent! Also there is some differences}
14
+ spec.homepage = "https://github.com/EhsanYousefi/Prong"
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.add_development_dependency "bundler", "~> 1.10"
23
+ spec.add_development_dependency "rake", "~> 10.0"
24
+ spec.add_development_dependency "rspec"
25
+ spec.add_development_dependency "pry"
26
+ end
data/test.rb ADDED
@@ -0,0 +1,5 @@
1
+ require 'pry'
2
+ def x(*args,{})
3
+ puts args; puts hash
4
+ end
5
+ binding.pry
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: prong
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Ehsan Yousefi
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-12-06 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.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
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: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
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: Prong is almost behave like ActiveSupport::Callbakcs in most of the cases.
70
+ It's let you define hooks, add callbacks to them, and conditionally run them whenever
71
+ you want. Prong is not just another one, It's faster! It's independent! Also there
72
+ is some differences
73
+ email:
74
+ - ehsan.yousefi@live.com
75
+ executables: []
76
+ extensions: []
77
+ extra_rdoc_files: []
78
+ files:
79
+ - ".gitignore"
80
+ - ".rspec"
81
+ - ".travis.yml"
82
+ - CODE_OF_CONDUCT.md
83
+ - Gemfile
84
+ - LICENSE.txt
85
+ - README.md
86
+ - Rakefile
87
+ - bin/console
88
+ - bin/setup
89
+ - lib/.DS_Store
90
+ - lib/prong.rb
91
+ - lib/prong/.DS_Store
92
+ - lib/prong/class_attr.rb
93
+ - lib/prong/class_methods.rb
94
+ - lib/prong/hooks/chain.rb
95
+ - lib/prong/hooks/define.rb
96
+ - lib/prong/hooks/executer.rb
97
+ - lib/prong/hooks/skip.rb
98
+ - lib/prong/hooks/skip_all.rb
99
+ - lib/prong/instance_methods.rb
100
+ - lib/prong/version.rb
101
+ - prong.gemspec
102
+ - test.rb
103
+ homepage: https://github.com/EhsanYousefi/Prong
104
+ licenses:
105
+ - MIT
106
+ metadata: {}
107
+ post_install_message:
108
+ rdoc_options: []
109
+ require_paths:
110
+ - lib
111
+ required_ruby_version: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - ">="
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ required_rubygems_version: !ruby/object:Gem::Requirement
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ requirements: []
122
+ rubyforge_project:
123
+ rubygems_version: 2.4.5.1
124
+ signing_key:
125
+ specification_version: 4
126
+ summary: Activesupport-like callbacks but upto %20 faster.
127
+ test_files: []