#12978: conditionally_defined decorator for methods and nested classes
-------------------------------------------------+-------------------------
       Reporter:  nthiery                        |        Owner:  jason
           Type:  enhancement                    |       Status:  new
       Priority:  major                          |    Milestone:  sage-
      Component:  misc                           |  wishlist
       Keywords:  categories,                    |   Resolution:
  conditionally_defined                          |    Merged in:
        Authors:                                 |    Reviewers:
Report Upstream:  N/A                            |  Work issues:
         Branch:                                 |       Commit:
   Dependencies:                                 |     Stopgaps:
-------------------------------------------------+-------------------------

Comment (by SimonKing):

 Nicolas, I have questions to this feature request.

 What do you want to happen, if the condition in "conditionally_defined" is
 not met? Raise an attribute error (probably yes)?

 It seems to me that in your proposal we would either have a certain method
 defined, or have it not defined at all. Wouldn't it be nice to have
 ''several'' implementations of a method, and choose one of them according
 to certain parameters?

 I guess the extended proposal could not be done by a simple decorator,
 because a decorator only expects a single function as input.

 Anyway. I think it would be possible to create a wrapper that is bound to
 the class and has a `__get__` method that will then choose one of the
 wrapped methods and bind it to a specific instance.

 Note that in an awkward manual way, it is probably already possible to
 mimic this behaviour. Something like:
 {{{
 class C:
     def __init__(self, n):
         self.n = n
     @lazy_attribute
     def fancy_method(self):
         if self.n>0:
             return self.method1
         return self.method2
     def method1(self, m):
         print "method 1"
         return self.n*m
     def method2(self, m):
         print "method 2"
         return self.n+m
 }}}
 Indeed, you would then have
 {{{
 sage: c1 = C(3)
 sage: c2 = C(-3)
 sage: c1.fancy_method(2)
 method 1
 6
 sage: c2.fancy_method(2)
 method 2
 -1
 }}}

 So, you suggest to have a decorator that makes this behaviour automatic?

 Perhaps the choice could be made exactly as in my example. The syntax
 could be:
 {{{
 class C:
     @conditional_method(some_function)
     def method_name(self, ...=)
         <the default implementation>
     def method1(...):
         <first alternative implementation of method_name>
     def method2(...):
         <second alternative implementation of method_name>
     ...
 }}}
 where some_function expects `self` as argument and returns a string
 `chosen_name`. And then, `self.method_name` will be overridden by
 `getattr(self,chosen_name)`; only if self has no attribute `chosen_name`
 (which is the case, e.g., if `chosen_name=""`), then the default
 implementation is returned.

 Do you think this is a good approach/good syntax?

--
Ticket URL: <http://trac.sagemath.org/ticket/12978#comment:1>
Sage <http://www.sagemath.org>
Sage: Creating a Viable Open Source Alternative to Magma, Maple, Mathematica, 
and MATLAB

-- 
You received this message because you are subscribed to the Google Groups 
"sage-trac" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sage-trac.
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to