<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -10,10 +10,12 @@ module Roleful
   end
   
   module InstanceMethods
+    # Gives an object temporary roles for the duration of the block.
     def with_role(*tmp_roles)
-      old = meta_def(:role) {tmp_roles }
+      old_role = method(:role)
+      meta_def(:role) { tmp_roles }
       result = yield
-      meta_eval { remove_method(:role) }
+      meta_eval { define_method(:role, old_role) }
       result
     end
     
@@ -44,9 +46,10 @@ module Roleful
       roles.each { |name| define_role(name.to_sym, options, &amp;block) }
     end
     
-    # Adapted from ActiveSupport, modified a bit to ease binding contexts
+    # Delegates method calls to the object's #role_proxy, accounting for
+    # cases when there are multiple roles for the given object.
     def delegate_permission(*methods)
-      options = methods.pop    
+      options = methods.pop
       raise ArgumentError, &quot;Delegation needs a target.&quot; unless options.is_a?(Hash) &amp;&amp; to = options[:to]
 
       methods.each do |method|</diff>
      <filename>lib/roleful/inclusion.rb</filename>
    </modified>
    <modified>
      <diff>@@ -9,14 +9,16 @@ module Roleful
       define_predicates
     end
 
-    def can(permission, &amp;block)
-      permission_name = &quot;can_#{permission}?&quot;
+    def can(sym, &amp;block)
+      handlers[sym] = block || proc { true }
       
-      handlers[permission] = block || proc { true }
-      meta_def(permission_name) { |target, *args| handle(target, permission, *args) }
-      
-      meta_delegate(permission_name)
-      add_permission(permission)
+      metaclass.class_eval(&lt;&lt;-END, __FILE__, __LINE__)
+        def can_#{sym}?(target, *args)
+          handle(target, #{sym.inspect}, *args)
+        end
+      END
+
+      register_permission(sym)
     end
     
     def can?(target, permission, *args)
@@ -25,6 +27,8 @@ module Roleful
         handle(target, permission, *args)
     end
     
+    # Used when the permission in question is granted for the
+    # role in question. TODO: Is this really necessary?
     def method_missing(sym, *args)
       method_id = sym.to_s
       match_permission_or_predicate?(method_id) ? superuser? : super
@@ -55,17 +59,18 @@ module Roleful
     
     def define_predicates
       meta_def(&quot;#{name}?&quot;) { true }
-      meta_delegate(&quot;#{name}?&quot;)
-      meta_delegate(&quot;can?&quot;)
+      delegate_predicate(&quot;#{name}?&quot;)
+      delegate_predicate(&quot;can?&quot;)
     end
     
-    def add_permission(permission)
+    def register_permission(permission)
       permission = permission.to_sym
       @permissions.add(permission)
       @klass::PERMISSIONS.merge(@permissions)
+      delegate_predicate(&quot;can_#{permission}?&quot;)
     end
     
-    def meta_delegate(name)
+    def delegate_predicate(name)
       @klass.delegate_permission name, :to =&gt; :role_proxy
     end
   end</diff>
      <filename>lib/roleful/role.rb</filename>
    </modified>
    <modified>
      <diff>@@ -36,7 +36,7 @@ describe Roleful do
     klass::ROLES[:admin].should_not be_nil
   end
   
-  describe &quot;role predicate helpers&quot; do
+  describe &quot;role name predicate helpers&quot; do
     before(:each) do
       klass.role :admin
     end
@@ -139,6 +139,41 @@ describe Roleful do
     end
   end
   
+  describe &quot;permission methods&quot; do
+    before(:each) do
+      klass.role(:paid)
+      klass.role(:admin) { can :view_foos }
+    end
+    
+    context &quot;for roles that have permission&quot; do
+      before(:each) do
+        @object = klass.new(:admin)
+      end
+      
+      it &quot;returns true&quot; do
+        object.can_view_foos?.should be_true
+      end
+      
+      it &quot;are known to be responded to&quot; do
+        object.respond_to?(:can_view_foos?).should be_true
+      end
+    end
+    
+    context &quot;for roles that don't have permission&quot; do
+      before(:each) do
+        @object = klass.new(:paid)
+      end
+      
+      it &quot;returns false&quot; do
+        object.can_view_foos?.should be_false
+      end
+      
+      it &quot;is known to be responded to&quot; do
+        object.respond_to?(:can_view_foos?).should be_true
+      end
+    end
+  end
+  
   describe &quot;with instance-specific permissions&quot; do
     before(:each) do
       klass.role :admin do
@@ -245,11 +280,8 @@ describe Roleful do
       object = klass.new
       object.can?(:be_awesome).should be_false
       
-      spec = self
-      object.instance_eval do
-        with_role(:awesome) do
-          can?(:be_awesome).should spec.be_true
-        end
+      object.with_role(:awesome) do
+        object.can?(:be_awesome).should be_true
       end
 
       object.can?(:be_awesome).should be_false
@@ -261,16 +293,33 @@ describe Roleful do
       object.can?(:be_awesome).should be_false
       object.can?(:be_bad_ass).should be_false
       
-      spec = self
-      object.instance_eval do
-        with_roles(:awesome, :bad_ass) do
-          can?(:be_awesome).should spec.be_true
-          can?(:be_bad_ass).should spec.be_true
-        end
+      object.with_roles(:awesome, :bad_ass) do
+        object.can?(:be_awesome).should be_true
+        object.can?(:be_bad_ass).should be_true
       end
       
       object.can?(:be_awesome).should be_false
       object.can?(:be_bad_ass).should be_false
     end
+    
+    it &quot;restores old singleton methods&quot; do
+      object = klass.new
+      class &lt;&lt; object
+        def role
+          :awesome
+        end
+      end
+      
+      object.should be_awesome
+      object.can?(:be_awesome).should be_true
+      
+      object.with_role(:bad_ass) do
+        object.should be_bad_ass
+        object.can?(:be_bad_ass).should be_true
+      end
+      
+      object.should be_awesome
+      object.can?(:be_awesome)
+    end
   end
 end
\ No newline at end of file</diff>
      <filename>spec/roleful_spec.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>72455a6333e2296edeb46d2a80cbff7ab2689bcc</id>
    </parent>
  </parents>
  <author>
    <name>Pat Nakajima</name>
    <email>patnakajima@gmail.com</email>
  </author>
  <url>http://github.com/nakajima/roleful/commit/4431f87ae24368840230c3bf4f9736c8bfb6215f</url>
  <id>4431f87ae24368840230c3bf4f9736c8bfb6215f</id>
  <committed-date>2008-12-01T18:14:20-08:00</committed-date>
  <authored-date>2008-12-01T18:14:20-08:00</authored-date>
  <message>fixed bug where #with_role would blow away singleton methods, a few code cleanups</message>
  <tree>9c0e10466488a432ede13171e388a0366e0aba50</tree>
  <committer>
    <name>Pat Nakajima</name>
    <email>patnakajima@gmail.com</email>
  </committer>
</commit>
