Ruby-like expression substitution in Python

I don’t know much Ruby, and probably won’t learn; all that syntax and magic scare me away. But I have to admit it has some darned useful gadgets. Here’s a python function I hacked up to do something much like Ruby’s expression-substitution, using the same #{ } syntax. It doesn’t allow curly braces inside the #{ }; were I a little less lazy I would put in some escaping.


import re
import sys

def esub(s):
    """
    Perform Ruby-like expression substitution.

    >>> x=3
    >>> y='A'
    >>> esub('abc#{x}def#{3+5}hij#{"".join([y, y])}')
    'abc3def8hijAA'
    """
    restr = r'(?:#{(?P[^{}]*)})|(?:[^#])+|#'
    fr = sys._getframe(1)
    def process(m):
        txt = m.group('exp')
        if txt is not None:
            val = eval(txt, fr.f_globals, fr.f_locals)
            return type(s)(val)
        else:
            return m.group()
    return ''.join(process(m) for m in re.finditer(restr, s))
Advertisements

Tags: , ,

2 Responses to “Ruby-like expression substitution in Python”

  1. ibtiwuksiwpdg Says:

    What’s about this:

    def m(a):
    def n():
    return esub(‘#{a}’)
    return n()

    m(42)

    your approach cannot deal with free variables in inner functions, unfortunately.

  2. mrlauer Says:

    D’oh! Oh well.

    A not-great workaround:

    def m(a):
    def n():
    a
    return esub(’#{a}’)
    return n()

    m(42)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: