#12953: Bindable classes
-------------------------------------+--------------------------------------
       Reporter:  nthiery            |         Owner:  jason          
           Type:  enhancement        |        Status:  positive_review
       Priority:  major              |     Milestone:  sage-5.1       
      Component:  misc               |    Resolution:                 
       Keywords:  days38             |   Work issues:                 
Report Upstream:  N/A                |     Reviewers:  Franco Saliola 
        Authors:  Nicolas M. ThiƩry  |     Merged in:                 
   Dependencies:                     |      Stopgaps:                 
-------------------------------------+--------------------------------------
Changes (by nthiery):

  * keywords:  => days38
  * status:  needs_review => positive_review


Old description:

> From the documentation:
> {{{
>     Bindable classes
>
>     This class implements a binding behavior for nested classes that
>     derive from it.
>
>     EXAMPLES:
>
>     Let us consider the following class ``Outer`` with a nested class
> ``Inner``::
>
>         sage: from sage.misc.nested_class import NestedClassMetaclass
>         sage: class Outer:
>         ...       __metaclass__ = NestedClassMetaclass # workaround for
> python pickling bug
>         ...       def f(self, *args):
>         ...           print self, args
>         ...
>         ...       @staticmethod
>         ...       def f_static(*args):
>         ...           print args
>         ...
>         ...       class Inner:
>         ...           def __init__(self, *args):
>         ...               print args
>         sage: obj = Outer()
>
>     By default, when Inner is a class nested in Outer, accessing
>     ``obj.Inner`` returns the ``Inner`` class as is::
>
>         sage: obj.Inner is Outer.Inner
>         True
>
>     In particular, ``obj`` is completely ignored in the following call::
>
>         sage: x = obj.Inner(1,2,3)
>         (1, 2, 3)
>
>     This is similar to what happens with a staticmethod::
>
>         sage: obj.f_static(1,2,3)
>         (1, 2, 3)
>
>     In some cases, we would want instead Inner to receive ``obj`` as
>     parameter, like in a usual method call::
>
>         sage: obj.f(1,2,3)
>         <__main__.Outer object at ...> (1, 2, 3)
>
>     To this end, ``obj.f`` returns a *bound method*::
>
>         sage: obj.f
>         <bound method Outer.f of <__main__.Outer object at ...>>
>
>     so that ``obj.f(1,2,3)`` is equivalent to::
>
>         sage: Outer.f(obj, 1,2,3)
>         <__main__.Outer object at ...> (1, 2, 3)
>
>     ``BindableClass`` gives this binding behavior to all its subclasses::
>
>         sage: from sage.misc.bindable_class import BindableClass
>         sage: class Outer:
>         ...       __metaclass__ = NestedClassMetaclass # workaround for
> python pickling bug
>         ...
>         ...       class Inner(BindableClass):
>         ...           " some documentation "
>         ...           def __init__(self, obj, *args):
>         ...               print obj, args
>
>     Now, ``obj.Inner(1,2,3)`` is equivalent to Outer.Inner(obj, 1,2,3)::
>
>         sage: obj = Outer()
>         sage: x = obj.Inner(1,2,3)
>         <__main__.Outer object at ...> (1, 2, 3)
> }}}

New description:

 From the documentation:
 {{{
     Bindable classes

     This class implements a binding behavior for nested classes that
     derive from it.

     EXAMPLES:

     Let us consider the following class ``Outer`` with a nested class
 ``Inner``::

         sage: from sage.misc.nested_class import NestedClassMetaclass
         sage: class Outer:
         ...       __metaclass__ = NestedClassMetaclass # workaround for
 python pickling bug
         ...       def f(self, *args):
         ...           print self, args
         ...
         ...       @staticmethod
         ...       def f_static(*args):
         ...           print args
         ...
         ...       class Inner:
         ...           def __init__(self, *args):
         ...               print args
         sage: obj = Outer()

     By default, when Inner is a class nested in Outer, accessing
     ``obj.Inner`` returns the ``Inner`` class as is::

         sage: obj.Inner is Outer.Inner
         True

     In particular, ``obj`` is completely ignored in the following call::

         sage: x = obj.Inner(1,2,3)
         (1, 2, 3)

     This is similar to what happens with a staticmethod::

         sage: obj.f_static(1,2,3)
         (1, 2, 3)

     In some cases, we would want instead Inner to receive ``obj`` as
     parameter, like in a usual method call::

         sage: obj.f(1,2,3)
         <__main__.Outer object at ...> (1, 2, 3)

     To this end, ``obj.f`` returns a *bound method*::

         sage: obj.f
         <bound method Outer.f of <__main__.Outer object at ...>>

     so that ``obj.f(1,2,3)`` is equivalent to::

         sage: Outer.f(obj, 1,2,3)
         <__main__.Outer object at ...> (1, 2, 3)

     ``BindableClass`` gives this binding behavior to all its subclasses::

         sage: from sage.misc.bindable_class import BindableClass
         sage: class Outer:
         ...       __metaclass__ = NestedClassMetaclass # workaround for
 python pickling bug
         ...
         ...       class Inner(BindableClass):
         ...           " some documentation "
         ...           def __init__(self, obj, *args):
         ...               print obj, args

     Now, ``obj.Inner(1,2,3)`` is equivalent to Outer.Inner(obj, 1,2,3)::

         sage: obj = Outer()
         sage: x = obj.Inner(1,2,3)
         <__main__.Outer object at ...> (1, 2, 3)
 }}}

 This feature will be extensively used for implementing
 SetsWithRealizations; see e.g. #12959 and the upcoming NCSF #8899 patch

--

Comment:

 On behalf of Franco:

 Comment: A variant would be to implement this feature using a class
 decorator. Practice will tell if we would need that variant. One advantage
 (or maybe sometimes an inconvenient?) of doing it by inheritance as
 implemented here is that all subclasses benefit from it, like, e.g., for
 UniqueRepresentation.

 Positive review!

-- 
Ticket URL: <http://trac.sagemath.org/sage_trac/ticket/12953#comment:2>
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 post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sage-trac?hl=en.

Reply via email to