[pypy-dev] Efficiently piecing together callables with hooks?

Timo Paulssen timonator at perpetuum-immobile.de
Mon Aug 15 19:43:50 CEST 2011


On 15.08.2011 10:18, Samuel Ytterbrink wrote:
> Hi, i only have some questions about your example code. How does the
> runhooks function work? And what are you using the pos loop variable for?

Hi,

here's all the code you'll need to understand what's going on:


    def step_pure_py(self):
        state = self.consts.copy()
        # self.attrs usually includes nconf and cconf, which are the
        # arrays that hold the cellular automaton configuration that's currently
        # being computed (nconf) and the last one (cconf)
        state.update(dict((k, getattr(self.target, k)) for k in self.attrs))

        def runhooks(hook):
            for hook in self.pycode[hook]:
                upd = hook(state)
                if isinstance(upd, dict):
                    state.update(upd)

        runhooks("init")
        loop_iter = self.loop.get_iter()
        for pos in loop_iter:
            state["pos"] = pos
            state.update(self.neigh.get_neighbourhood(pos))
            runhooks("pre_compute")
            runhooks("compute")
            runhooks("post_compute")
        runhooks("after_step")
        # flip current and next config for the next step
        self.target.nconf, self.target.cconf = \
            self.target.cconf, self.target.nconf


    # one example for a hook:
    # rule is an array that defines when to set the next cell state to 0 or 1
    # with this, you can create all elementary cellular automatons.
    binRuleTestCode.add_py_hook("compute",
            lambda state: dict(result=state["rule"][int(state["l"] * 4 +
                                      state["m"] * 2 + state["r"])]))


the "l", "m" and "r" variables get set by the LinearNeighbourhood class, which
adds the following hook:

    self.code.add_py_hook("pre_compute",
            lambda state, code=self.code: dict(zip(self.names,
                [self.code.acc.read_from(state["pos"] + offset)
                    for offset in self.offsets])))

where names would be list("lmr") and offsets would be (-1, 0, 1). self.code.acc
is the class that handles how access to the array is supposed to work.

I think I am going to kick out the lambda expressions that are supposed to
return a dict that would update the state dict and just use complete callables
instead, that directly manipulate it.

I hope this was enlightening.
  - Timo Paulssen

PS: i wonder how big the impact of defining the runhooks function inside the
step function?

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 262 bytes
Desc: OpenPGP digital signature
URL: <http://mail.python.org/pipermail/pypy-dev/attachments/20110815/24aa67c4/attachment.pgp>


More information about the pypy-dev mailing list