diff options
| author | Daniel Pittman <daniel@puppetlabs.com> | 2011-04-12 20:51:16 -0700 |
|---|---|---|
| committer | Daniel Pittman <daniel@puppetlabs.com> | 2011-04-13 14:03:48 -0700 |
| commit | 78e181e83d53a83a5c4e297d557b33f70a344039 (patch) | |
| tree | 44aab655bf89c87bac8bbf94c381da02d3f733b3 /lib | |
| parent | cc0f4141e17939bdfa4e8e6f84921161041507ef (diff) | |
| download | puppet-78e181e83d53a83a5c4e297d557b33f70a344039.tar.gz puppet-78e181e83d53a83a5c4e297d557b33f70a344039.tar.xz puppet-78e181e83d53a83a5c4e297d557b33f70a344039.zip | |
(#7059) handle inherited action binding scope
We implemented the naive version of inheritance in the faces, in which an
action declared on a superclass remains bound to that even when accessed
from a subclass.
As a consequence our visibility of options on inherited classes is actually
much more limited than it should be, and the actions we inherit would never
see the options they should correctly have.
To fix this we correct the binding bug and handle lookup correctly over
inheritance in our code.
Reviewed-By: Pieter van de Bruggen <pieter@puppetlabs.com>
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/puppet/interface/action.rb | 9 | ||||
| -rw-r--r-- | lib/puppet/interface/action_manager.rb | 11 |
2 files changed, 18 insertions, 2 deletions
diff --git a/lib/puppet/interface/action.rb b/lib/puppet/interface/action.rb index 302e61901..db338e39e 100644 --- a/lib/puppet/interface/action.rb +++ b/lib/puppet/interface/action.rb @@ -11,6 +11,15 @@ class Puppet::Interface::Action attrs.each do |k, v| send("#{k}=", v) end end + # This is not nice, but it is the easiest way to make us behave like the + # Ruby Method object rather than UnboundMethod. Duplication is vaguely + # annoying, but at least we are a shallow clone. --daniel 2011-04-12 + def __dup_and_rebind_to(to) + bound_version = self.dup + bound_version.instance_variable_set(:@face, to) + return bound_version + end + attr_reader :name def to_s() "#{@face}##{@name}" end diff --git a/lib/puppet/interface/action_manager.rb b/lib/puppet/interface/action_manager.rb index bb0e5bf57..d75697afa 100644 --- a/lib/puppet/interface/action_manager.rb +++ b/lib/puppet/interface/action_manager.rb @@ -35,9 +35,16 @@ module Puppet::Interface::ActionManager result = @actions[name.to_sym] if result.nil? if self.is_a?(Class) and superclass.respond_to?(:get_action) - result = superclass.get_action(name) + found = superclass.get_action(name) elsif self.class.respond_to?(:get_action) - result = self.class.get_action(name) + found = self.class.get_action(name) + end + + if found then + # This is not the nicest way to make action equivalent to the Ruby + # Method object, rather than UnboundMethod, but it will do for now, + # and we only have to make this change in *one* place. --daniel 2011-04-12 + result = @actions[name.to_sym] = found.__dup_and_rebind_to(self) end end return result |
