How about we just do this:
db.define_table('x',Field('number','integer'))
if db(db.x).isempty(): [db.x.insert(number=i) for i in range(10)]
db.x.normal_shift = Field.Virtual(lambda row: row.x.number+1)
db.x.lazy_shift = Field.Lazy(lambda row, delta=3: row.x.number+delta)
for row in db(db.x).select():
print row.number, row.normal_shift, row.lazy_shift(8)
It is in trunk already, not as a replacement but as an alternative.
Pros:
- simpler syntax
Cons:
- we can only attach virtual fields to a table not to a join (even if
each table in the joins will have virtual fields)
- they will not appear in crud.read and table forms unless passed
explicitly. (*)
(*) In principle this can be changed as one can envision adding
Field.Virtual in the model and giving them attributes like a label,
comment, etc. But that would require major refactoring.
On Aug 20, 7:04 am, Massimo Di Pierro <[email protected]>
wrote:
> OK try:
>
> db=DAL()
> db.define_table('x',Field('number','integer'))
> if db(db.x).isempty(): [db.x.insert(number=i) for i in range(10)]
>
> from gluon.dal import lazy_virtualfield
>
> class MyVirtualFields(object):
> # normal virtual
> field
> def normal_shift(self): return self.x.number+1
> # lazy virtual field (because of
> @staticmethod)
> @lazy_virtualfield
> def lazy_shift(self,row,delta=4): return row.x.number+delta
>
> db.x.virtualfields.append(MyVirtualFields())
>
> for row in db(db.x).select():
> print row.number, row.normal_shift, row.lazy_shift(8)
>
> It is better? We have one new API and one import. I do not like so
> much the try of adding a __lazy__ attribute to the function because,
> in the future the function may be a class with a __call__ method and
> te decorator would mess up class attributes.... perhaps we should
> this dicusssion and tests on web2py-delevelopers
>
> Massimo
>
> On Aug 20, 6:46 am, Massimo Di Pierro <[email protected]>
> wrote:
>
>
>
>
>
>
>
> > Yes but if we use lazy we have to define and import it from somewhere.
> > There is another reason. Using staticmethod we can also do
>
> > class A(): pass
> > a=A()
>
> > a.f=lambda(instance,row,*a,**b): return 'lazy value'
> > a.g=lambda(instance,row,*a,**b): return 'lazy value'
> > a.h=lambda(instance,row,*a,**b): return 'lazy value'
>
> > db.table.virtualfields.append(a)
>
> > Lat me give it a try anyway...
>
> > On Aug 20, 5:51 am, Bruno Rocha <[email protected]> wrote:
>
> > > why static_method is used to define this? not better to have some @lazy
> > > decorator?