Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

Things I love about .Net

PLEASE CORRECT ME IF I AM WRONG – I WANT TO BE WRONG

I have tried to figure out how to do this in python and ruby and I just can’t seem to find the right libs.

public class Helper
{
    public static  void ExploreAst<T>(Expression<Function<T, object>> expression)
    {
         // do stuff with the AST
    }
}
//later

Helper.ExploreAst&lt;object&gt;(o=&gt;o.ToString());

If I try to do this in python, no bueno.

class MyObj(Class):
    def my_method()
        pass

def exploreAst(expression):
    #do stuff with ast
    pass

# later
exploreAst(MyObj.my_method)
#boom!

Why boom? Because python is a lossy language. Once it has been compiled you lose some of the sweet sauce of python that .net will still maintain. There are a few libraries that try to help you out. What’s even worse is that you can’t do this with fields in python because (duh!) it passes in the VALUE of the field. After all, python has no idea that you don’t want the value. Honestly, my guess is that this is not the best way to approach the problem in python. Big surprise here: I am being the guy that is trying to fit a square peg in a round hole and wondering why it doesn’t work. Silly me.

Anyone have any ideas, I really like the Fluent NHibernate mapping model and would love to bring it to other languages.

-d

About Dru Sellers

Sr. Software Engineer at Dovetail Software.
This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • http://twitter.com/RobAshton Rob Ashton

    I was doing some more advanced expression parsing though, my gists are here:

    https://gist.github.com/1283813

  • http://twitter.com/RobAshton Rob Ashton

    I was looking at something similar with Javascript only very recently – just like in the other dynamic languages you have an issue where while you can parse the AST (in JS, there is uglify to do this) – and extract literal values – but when it comes to walking the stack to get values from variables there is no support at all.

    I opted for an intermediate compilation stage which can achieve this, but haven’t released the code because in a dynamic language there is a lot less value from doing this compared to just passing in a string.

  • Luchoregistration

    Instead of “No bueno” you should say “No esta bien”, or “No me fue bien”

  • Mark Gemmill

    From a glance at its intro Fluent NHibernate looks a lot like Python’s SqlAlchemy declarative extension. SqlAlchemy wraps up an entities attributes in it’s own property accessors which allows it to do the kinds of things you’re wanting to do.  You could also have a look at python property and descriptor constructs and the inspect module as a start.

  • Anonymous

    I think you would get better results if you explained the problem you are trying to solve, rather than asking for a direct equivalent (unless you aren’t really trying to solve a problem, and just tinkering).
    In ruby, if you want to to refer to a method as an argument to another method, you would pass its name as a symbol – no need for expression decompiling:do_something(:method_to_refer_to)You now have access to both the name of the method, and assuming you have an object instance, can easily get the methods value for that instance (via the send method built in to all objects).

    If you are trying to do deeper analysis of the code, you might use something like Ripper in ruby 1.9.
    You could also look to rubinius for richer access to the AST.
    But again, all of that may be overboard depending on the problem you are trying to solve. 

  • Anonymous

    class Person(object):
        def __init__(self):
            self.name = ‘dru’

    p  = Person()
    helper = MyMagicCodeThatReadsAsts()

    helper.whichFieldWasSelected(p.name)
    #outputs ‘name’

  • Anonymous

    it doesn’t help that I totally failed with saying I wanted to get the field name and then showed a method. #palmToForehead

  • Beau Lyddon

    Hey Dru, I’m a Python dev and could possibly help but your examples are a little confusing to me. I haven’t touched C# in years so I’m a bit behind on the syntax. What exactly are you trying accomplish here?

  • http://www.facebook.com/profile.php?id=63200313 Matt Trej Barr

    I answered, then tried to code something realistic and workable, then realized the ast class expects source code or nodes, not code objects and bytecode, so I started down a path of decompiling the byte code you can get easily into the source script, then making the ast, it’s doable but ugly,  should be pretty easy to wrap the ast in your own module that will take methods and classes, find their source code, and create ast nodes out of it.

    Good luck and let me know how it goes!

  • Anonymous

    from what I have read the func_code is not workable. and I don’t want to explore methods i want to explore fields. 😉 But you are 100% correct that I have the filename/object source code always. …. hmmmm … good idea. thanks. !!

  • Anonymous

    pshaw. closure. 😉 if I am going to do that I would just go lisp baby. all the way. 😉

  • Anonymous

    Agreed, but those aren’t python. with python libs. :)

  • Julian Birch

    I think it’s time to learn Clojure… none of the restrictions C# (or Boo) for that matter have on what, exactly, you can do this to.  

  • Seth

    You could use Boo, which is _like_ Python but with AST and compiler macro’s (which are a little bit like expression tree literals). 

    Or just use IronPython :)

  • http://www.facebook.com/profile.php?id=63200313 Matt Trej Barr

    #Your example had syntax errors anyway, but here’s a starting point
    import ast

    class MyObj(object):
        def my_method():
            x = 1
            y = 2
            z = x + y
            pass

    def exploreAst(expression):
        print dir(expression.im_func.func_code)
        print dir(ast)
        pass

    # later
    exploreAst(MyObj.my_method)
    #I don’t see where the boom is? Is it because you want the string source to create ast nodes?
    #You have the filename and object names of everything you’re interested in, I believe

  • Thor Arne Johansen

    Not sure exactly how the NH fluent mappings are related to this, but there is an AST lib for CPython (http://docs.python.org/library/ast.html)

  • http://dev.bennage.com Christopher Bennage

    I’m a total Ruby n00b, so my experience isn’t worth much, but I wanted to try to do the same thing in Ruby and when I asked around no one was able to help me. I didn’t dig too hard though. I’d love to see a solution.
    I wonder if this is a thing that Rubyists never _need_ to do, and that my C#ish way of thinking leads me down the wrong path.

  • Anonymous

    Perhaps in Ruby you can use the instance_method method to achieve what you want.

    http://www.ruby-doc.org/core-1.9.2/Module.html#method-i-instance_method