Welcome, guest | Sign In | My Account | Store | Cart
#!/usr/bin/env python

import UserList

class Collection(UserList.UserList):
    """Collections group objects together and forward attribute lookups.

    At least this is the Collection I remember from LYMB (an interpreted OO
    language developed by Bill Lorensen et al at GE CRD), which almost
    certainly got it from Smalltalk.
    """

    def get(self, attr):
        """return a list of attributes from ourselves.

        note that an object in the collection is not required to have 'attr',
        so the result may be shorter than the collection itself."""
        return Collection([getattr(x, attr) for x in self if hasattr(x, attr)])

    def call(self, attr, *args, **kwds):
        """return the result of calling 'attr' for each of our elements"""
        attrs = self.get(attr)
        return Collection([x(*args, **kwds)
                             for x in attrs
                               if callable(x)])

if __name__ == "__main__":
    import time

    class Food:
        def __init__(self):
            self.t = time.time()
            time.sleep(0.5)

    class Ham(Food):
        def say(self):
            print "I am Ham, and I don't want any arguments, thank you."
            return ()

        def speak_up(self, arg):
            print 'I am Ham, and my arguments are %s' % arg
            return arg

    class Eggs(Food):
        def speak_up(self, arg='bacon'):
            print 'I am Eggs, and my arguments are %s' % arg
            return arg

    class Spam(Food):
        def shout(self, arg1, arg2='sausage'):
            print 'I AM SPAM AND MY ARGUMENTS ARE %s AND %s' % (arg1, arg2)
            return (arg1, arg2)

    c = Collection()
    # kind of boring example...
    c.extend(range(3))
    print c.get("__hash__")
    print c.call("__hash__")
    print

    # slightly more interesting example...
    c = Collection([Ham(), Eggs(), Spam()])

    print "*** when was this food made? ***"
    times = c.get("t")
    print map(round, times, [2]*len(times))
    print

    print "*** what kind of food is it? ***"
    print c.get("__class__").get("__name__")
    print

    print "*** shouting ***"
    print c.call("shout", "nickel", "dime")
    print

    print "*** speaking up ***"
    print c.call("speak_up", "juice please")
    print

    print "*** saying ***"
    print c.call("say")
    print

History