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