Which is less confusing/annoying?

60 views
Skip to first unread message

Griatch Art

unread,
Feb 23, 2012, 10:18:51 AM2/23/12
to eve...@googlegroups.com
In the dev blog Such a Small Thing, I outline some of the underlying difficulting with implementing easy-to-use Attributes. There is however a side effect of this that is not mentioned, and which leads to what may not behave as you would expect.

Consider the following situation: 

obj.db.test = [1,2,3,4]

This saves the list to an attribute 'test'. 

test = obj.db.test

This retrieves the stored list - but it is not a list anymore! It's a PackedList, an object that saves every change to itself to the database. So type(test)==list will fail. 
The reason for making it such is to allow for the in-sity assignment of data, like obj.db.test[2] = val (further nesting than that doesn't work). 

Anyway, assume that we, with our newly fetched variable, we now do

test[2] = 4

You are updating the list as expected, but you are also right away saving it to the database, because this is what PackedLists do. This is not at all intuitive and might even be very confusing if you expect to be working on a normal list away from the database. Using test = list(test) will convert it to a "normal" list, but who will remember to do this?. 

Dictionaries have the same behaviour, returning a PackedDict.

So my question to those reading this list is this: 


Is the ability to do e.g. obj.db.test[2] = 1 worth the tradeoff of getting PackedDicts/PackedList's back from Attributes? 

If not, instead of obj.db.test[2] = 4 directly, one would need to do
 
temp = obj.db.test
temp[2] = 4
obj.db.test = temp 

instead. It's certainly more consistent, although also more cumbersome. I'm really quite split on this.
.
Griatch

Doug Miller

unread,
Feb 23, 2012, 10:45:40 AM2/23/12
to eve...@googlegroups.com
I like the second method after discussing it in IRC with you.  I see it as very natural to think 'get this out of the db, modify it, store it back if i want to keep this' methodology.

Trying to keep to 'the python way' is important but I would say method #2 isn't that far from it.  And being 'real' lists/dictionaries instead of packed may avoid confusion for developers.

Griatch

--
You received this message because you are subscribed to the "Evennia" MU* server mailing list.
To post to this group, send email to eve...@googlegroups.com (or use the web interface).
To unsubscribe from this group, send email to evennia+u...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/evennia?hl=en

gsb

unread,
Feb 23, 2012, 12:51:00 PM2/23/12
to eve...@googlegroups.com
We've talked about this a bit in IRC as well.  It seems more natural to me to retrieve, modify, save when I need to do something with attributes.  I guess when reading my code it just seems very, very clear what I'm doing when I write it out that way.  So I guess doing it the 'long' way leads to more readable code, which I am a fan of.

I do think its nice to have the other method available however, and haven't run in to any problems yet in my game system design where the type being PackedList or PackedDict caused any issues.

So i guess im for leaving it as it is, but perhaps it should be well documented whats going on behind the scenes.  As long as the developer is aware, i can't see it really causing issues.

--geoff

jeremyosborne

unread,
Feb 23, 2012, 3:48:08 PM2/23/12
to Evennia
I use the shelve module every now and then, and by default shelve
requires specific assignment to the key to cause persistence.

As such:

# Copy in memory
temp = obj.db.test
temp[2] = 4
# persist to disk
obj.db.test = temp

Is more natural to me in the python world. In other code, which is
mainly JavaScript, all persistence (what little of it there is on the
client side) is explicit, and unless noted I'm dealing memory only.

The PackedList is a cool idea, but I see it useful from a Builder
perspective, not necessarily an implementor (coder) perspective.
Builders, who are usually quite creative and smart but aren't always
coders in "real life" might have use of something like the PackedList
exposed in their code. A cave-in happens in a room that we want to be
permanent and immediately written to disk. Always good to not throw
the baby out with the bathwater, unless the baby is named Damien or
Regan or TheBadSeed ;)

- Jeremy

On Feb 23, 7:18 am, Griatch Art <gria...@gmail.com> wrote:
> In the dev blog Such a Small Thing<http://evennia.blogspot.com/2012/02/such-small-thing.html>,
> I outline some of the underlying difficulting with implementing easy-to-use
> Attributes. There is however a side effect of this that is not mentioned,
> and which leads to what may not behave as you would expect.
>
> Consider the following situation:
>
> obj.db.test = [1,2,3,4]
>
> This saves the list to an attribute 'test'.
>
> test = obj.db.test
>
> This retrieves the stored list - but it is not a list anymore! It's a
> PackedList, an object that saves every change to itself to the database. So
> type(test)==list will fail.
> The reason for making it such is to allow for the in-sity assignment of
> data, like obj.db.test[2] = val (further nesting than that doesn't work).
>
> Anyway, assume that we, with our newly fetched variable, we now do
>
> test[2] = 4
>
> You are updating the list as expected, *but you are also right away saving
> it to the database, because this is what PackedLists do. *This is not at
> all intuitive and might even be very confusing if you expect to be working
> on a normal list away from the database. Using test = list(test) will
> convert it to a "normal" list, but who will remember to do this?.
>
> Dictionaries have the same behaviour, returning a PackedDict.
>
> So my question to those reading this list is this:
>
> *Is the ability to do e.g. obj.db.test[2] = 1 worth the tradeoff of getting
> PackedDicts/PackedList's back from Attributes? *

Griatch Art

unread,
Mar 22, 2012, 10:44:02 AM3/22/12
to eve...@googlegroups.com
The responses so far seem to be two in favor of an explicit scheme, one for keeping it as it is (i.e. keep PackedDict/List). 

I have looked into various options, but there does not seem to be any other way to get the best of both worlds in this case - supporting in-situ saving (obj.db.mylist[1] = val) does require the use of something like PackedList/PackedDict. This solution is considerably more sophisticated than the explicit scheme, but it is already implemented and works. In the cases where it matters, one can always do a = list(obj.db.mylist) to be sure to cut the connection to the database ...

I remain on the fence for this, but for now I'll go the cheapest route and not remove already implemented functionality. 
.
Griatch
Reply all
Reply to author
Forward
0 new messages