Sorry for the lat reply. This is not a bug. This is a design issue and
tradeoff.

In fact there is a single virtualfields instance, the one you create
in:

   db.test.virtualfields.append(TestLazy())

and not one instance per record. There are two reasons for this:
1) allows cumulative virtualfields (values that depends on previous
records)
2) save memory

You can replace your code

class TestLazy:
    def lazy_test_field(self):
        def lazy(self=self):
            return self.test.name
        return lazy

with

class TestLazy:
    def lazy_test_field(self):
        from copy import copy
        def lazy(self=copy(self)):
            return self.test.name
        return lazy

and this would work as you expect. It is just that DAL leaves to you
the responsibility of making the copy and using the extra memory and
does not do it automatically because most of the cases it would be a
waste.

Massimo

On Aug 21, 6:22 pm, Niphlod <niph...@gmail.com> wrote:
> so, I read the docs and.....
>
> I think either there's a bug or I'm doing something wrong....
>
> in db.py
>
> ---------------
> .....
>
> db.define_table('test',
>                 Field('name', length=5)
>                 )
>
> class TestLazy:
>     def lazy_test_field(self):
>         deflazy(self=self):
>             return self.test.name
>         returnlazy
>
> class TestNotLazy:
>     def not_lazy_test_field(self):
>         return self.test.name
>
> db.test.virtualfields.append(TestLazy())
> db.test.virtualfields.append(TestNotLazy())
>
> ----------------
>
> Testing in the shell
>
> web2py Shell Version 1.83.2 (2010-08-15 08:16:30)
> In[0]:  set = db(db.test.id>0).select()
>
> Out[0]:
> In[1]:  set.as_dict()
>
> Out[1]: {1: {'name': 'miao', 'id': 1, 'not_lazy_test_field': 'miao'},
> 2: {'name': 'bau', 'id': 2, 'not_lazy_test_field': 'bau'}}
>
> In[2]:for row in set:
>     print row.id, row.name, row.not_lazy_test_field
>
> Out[2]:
> 1 miao miao
> 2 bau bau
>
> In[3]:
> for row in set:
>     print row.id, row.name, row.not_lazy_test_field,
> row.lazy_test_field
>
> Out[3]:
> 1 miao miao <functionlazyat 0x2e5c2a8>
> 2 bau bau <functionlazyat 0x308ec80>
>
> In[4]:
> for row in set:
>     print row.id, row.name, row.not_lazy_test_field,
> row.lazy_test_field()
>
> Out[4]:
> 1 miao miao bau
> 2 bau bau bau
>
> sorry for the unmeaning data in the set, but...seems thatlazy
> virtualfield is evaluated every line (different hash function when you
> try to print row.lazy_test_field without parenthesis, In[3]) but it
> returns data computed for the last line in the set...in all the rows
> of the set itself (In[4])
>
> Can somebody point me in the right direction ?
> Thanks

Reply via email to