Skip to content

Commit

Permalink
Issue #53 Add support for private callback methods again - but only i…
Browse files Browse the repository at this point in the history
…n the immediate class
  • Loading branch information
geekq committed Jan 20, 2013
1 parent 66a0d31 commit c9aa08c
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 11 deletions.
10 changes: 5 additions & 5 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -503,14 +503,14 @@ Changelog

### New in the version 0.9.0

* **Use protected callback methods.**
If you wish to use non-public callback methods, you now have to switch
from private to protected methods. See also issues
[#53](https://github.com/geekq/workflow/pull/53)
* **Support to priavate/protected callback methods.**
See also issues [#53](https://github.com/geekq/workflow/pull/53)
and [#58](https://github.com/geekq/workflow/pull/58). With the new
implementation:

* callback methods can be hidden (non public)
* callback methods can be hidden (non public): both private methods
in the immediate class and protected methods somewhere in the class
hierarchy are supported
* no unintentional calls on `fail!` and other Kernel methods
* inheritance hierarchy with workflow is supported

Expand Down
9 changes: 7 additions & 2 deletions lib/workflow.rb
Original file line number Diff line number Diff line change
Expand Up @@ -284,9 +284,14 @@ def run_after_transition(from, to, event, *args)
def run_action(action, *args)
instance_exec(*args, &action) if action
end

def has_callback?(action)
self.respond_to?(action) or self.class.protected_method_defined?(action)
# 1. public callback method or
# 2. protected method somewhere in the class hierarchy or
# 3. private in the immediate class (parent classes ignored)
self.respond_to?(action) or
self.class.protected_method_defined?(action) or
self.private_methods(false).map(&:to_sym).include?(action)
end

def run_action_callback(action_name, *args)
Expand Down
24 changes: 20 additions & 4 deletions test/main_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -291,24 +291,40 @@ def another_transition(args)

test '#53 Support for non public transition callbacks' do
args = mock()
args.expects(:log).once
c = Class.new
args.expects(:log).with('in private callback').once
args.expects(:log).with('in protected callback in the base class').once

b = Class.new # the base class with a protected callback
b.class_eval do
protected
def assign_old(args)
args.log('in protected callback in the base class')
end
end

c = Class.new(b) # inheriting class with an additional protected callback
c.class_eval do
include Workflow
workflow do
state :new do
event :assign, :transitions_to => :assigned
event :assign_old, :transitions_to => :assigned_old
end
state :assigned
state :assigned_old
end

protected
private
def assign(args)
args.log('Assigned')
args.log('in private callback')
end
end

a = c.new
a.assign!(args)

a2 = c.new
a2.assign_old!(args)
end

test '#58 Limited private transition callback lookup' do
Expand Down

0 comments on commit c9aa08c

Please sign in to comment.