[albatross-users] impedance mismatch 1

Matt Goodall matt at pollenation.net
Wed Jul 2 10:18:57 EST 2003


Oh boy, I hope I get this right. I **really** hope it helps and doesn't
just confuse you more. See the comments below.

Cheers, Matt

On Tue, 2003-07-01 at 23:45, Eric S. Johansson wrote:
> The description of locals leaves me puzzled.  Its behavior is counter to 
> everything I have learned in Python to date.  It's this magic data lint trap 
> that doesn't behave like a class, a dictionary, a list or anything else I'm 
> familiar with.

OK, I think I understand what you mean about locals now and where your
confusion comes from. locals is simply an empty class definition:

    class Vars:
        pass
    ...
    ctx.locals = Vars()

Python allows you to set any attribute on any object at any time:

    v = Vars()
    v.my_name = 'Matt'

This is perfectly valid and fairly normal in Python. After all, you
don't have to define instance attributes, you just say "self.my_name =
'Matt'".

This reminds me that I have a note in a text file somewhere that says
something like, "could/should ctx.locals behave like a dictionary?".

I think ctx.locals could be made to behave like a dictionary. An initial
(untested) implementation of Vars to support this might be:

    class Vars:
        def __setitem__(self, name, value):
            setattr(self, name, value)
        def __getitem__(self, name):
            return getattr(self, name)
        etc

That means you can treat a Vars instance as an object or a dictionary,
depending on your preference:

    >>> v = Vars()
    >>> v.a = 'a'
    >>> v['b'] = 'b'
    >>> vars(v)
    {'a': 'a', 'b': 'b'}
    >>> v.a
    'a'
    >>> v['a']
    'a'
    >>> v.b
    'b'
    >>> v['b']
    'b'

There are other methods that would need implementing for Vars to be
truly dictionary-like but I'm sure you get the idea.

Eric, would making ctx.locals behave like a dictionary help your
understanding? Dave/Andrew, are there any technical reasons why this
would not work?

> 
> But I guess I can sort of deal with the dissonance by just assuming that 
> context.locals can magically absorb data and associate it with a statically 
> supplied name.

Hopefully, it's not so magic now ;-).

> 
> quite frankly, most of the discussion about local and global name spaces just 
> goes in one ear and out the other because it just doesn't seem important to the 
> problem on hand of figuring out how to transfer data from the local context to 
> the template context.

I must admit, I need to find out about the global name space!

> 
> Now comes the templates and I get really confused.
> 
> expr=name.value()
> 
> brings an exclamation of wth?? to my lips.  Why isn't it just name?  what 
> happened to the ctx.locals?  Eventually I just shrug and figure it's for some 
> hopefully documented reason.  But the next line really brings wrinkles to my brow
> 
> expr="environ[name.value()]"
> 
> after all if name needs a .value() function why isn't it
> 
> expr="environ[name.value()].value()"
> 
> seriously grump inspiring.

OK, here goes ...

What happened to the ctx.locals
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In a template the scope *is* ctx.locals, i.e. any reference to a
variable called 'my_name' actually means ctx.locals.my_name. You publish
object for the template by storing them in ctx.locals. Earlier, you
talked about the need to "associate a dictionary with an albatross HTML
template"; that's what ctx.locals does.

expr="name.value()" ... Why isn't it just name?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Here's the important bit in the documentation from section 5.3.7,
http://www.object-craft.com.au/projects/albatross/albatross/tag-for.html.

        "The tag uses an instance of the ListIterator identified in the
        local namespace by the iter attribute to iterate over the
        sequence defined by the expression in the expr attribute."

If you look at ListIterator's methods it will probably make more sense
now. It is ListIterator that makes the paging possible and the index()
can be used for things like colouring alternate rows, i.e.
"name.index()%2 and 'red' or 'green'".

By the way, Dave has only just updated this bit of documentation based
on feedback on the list so don't feel bad about missing the importance
of ListIterator. It was documented but it was not as clear as it could
have been.

why isn't it environ[name.value()].value()
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
So, why isn't the .value() needed on the end? Hopefully you now
understand that:

      * "name" is a ListIterator created by the <al-for> tag to iterate
        over the items in "keys"
      * "name.value()" is the current item from "keys"
      * "environ" when inside the template refers to the same dictionary
        as "ctx.locals.environ" in the python code.

So all "environ[name.value()]" is actually doing is getting the value of
the item in environ that has a key name.value(). The <al-value> tag has
no need to create anything like the ListIterator as all it does is print
some text to the page.

-- 
Matt Goodall, Pollenation Internet Ltd
w: http://www.pollenation.net
e: matt at pollenation.net



More information about the Albatross-users mailing list