espeed / bulbs

A Python persistence framework for graph databases like Neo4j, OrientDB and Titan.
http://bulbflow.org
Other
623 stars 82 forks source link

Multi-line closures in Gremlin script & function definitions #67

Closed amergin closed 11 years ago

amergin commented 12 years ago

Regular expression fetching the functions seems to be faulty:

bash-4.1$ cat short2.groovy 
def short2()
{
    return g.v(1234).outE.filter
    {
        return (it.pvalue > 0) ||
        (it.correlation < 0);
    };
}

>>> g.scripts.update('short2.groovy')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/lineo4j/.local/lib/python2.7/site-packages/bulbs/groovy.py", line 69, in update
    methods = self._get_methods(file_path)
  File "/home/lineo4j/.local/lib/python2.7/site-packages/bulbs/groovy.py", line 89, in _get_methods
    return Parser(file_path).get_methods()
  File "/home/lineo4j/.local/lib/python2.7/site-packages/bulbs/groovy.py", line 184, in __init__
    Scanner(handlers).scan(groovy_file)
  File "/home/lineo4j/.local/lib/python2.7/site-packages/bulbs/groovy.py", line 175, in scan
    self.get_item(fin,line)
  File "/home/lineo4j/.local/lib/python2.7/site-packages/bulbs/groovy.py", line 166, in get_item
    callback(self,content)
  File "/home/lineo4j/.local/lib/python2.7/site-packages/bulbs/groovy.py", line 192, in add_method
    method_signature = self._get_method_signature(method_definition)
  File "/home/lineo4j/.local/lib/python2.7/site-packages/bulbs/groovy.py", line 206, in _get_method_signature
    return re.search(pattern,method_definition).group(1).strip()
AttributeError: 'NoneType' object has no attribute 'group'

This seems to be due to \n between def [functionname] and '{' because removing it will remove the problem:

bash-4.1$ cat short.groovy 
def short() {
    return g.v(1234).outE.filter
    {
        return (it.pvalue > 0) ||
        (it.correlation < 0);
    };
}

>>> g.scripts.update('short.groovy')
>>> 

Seems there's also a problem with closures split to several lines:

>>> s = g.scripts.get('short')
>>> g.gremlin.query(s)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/lineo4j/.local/lib/python2.7/site-packages/bulbs/gremlin.py", line 62, in query
    resp = self.client.gremlin(script, params)
  File "/home/lineo4j/.local/lib/python2.7/site-packages/bulbs/neo4jserver/client.py", line 384, in gremlin
    return self.request.post(path, params)
  File "/home/lineo4j/.local/lib/python2.7/site-packages/bulbs/rest.py", line 126, in post
    return self.request(POST, path, params)
  File "/home/lineo4j/.local/lib/python2.7/site-packages/bulbs/rest.py", line 181, in request
    return self.response_class(http_resp, self.config)
  File "/home/lineo4j/.local/lib/python2.7/site-packages/bulbs/neo4jserver/client.py", line 217, in __init__
    self.handle_response(response)
  File "/home/lineo4j/.local/lib/python2.7/site-packages/bulbs/neo4jserver/client.py", line 249, in handle_response
    response_handler(response)
  File "/home/lineo4j/.local/lib/python2.7/site-packages/bulbs/rest.py", line 36, in bad_request
    raise ValueError(http_resp)
ValueError: ({'status': '400', 'content-length': '1122', 'content-encoding': 'UTF-8', 'server': 'Jetty(6.1.25)', 'access-control-allow-origin': '*', 'content-type': 'application/json'}, '{\n  "message" : "org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:\\nScript26.groovy: 90: Ambiguous expression could be a parameterless closure expression, an isolated open code block, or it may continue a previous statement;\\n   solution: Add an explicit parameter list, e.g. {it -> ...}, or force it to be treated as an open block by giving it a label, e.g. L:{...}, and also either remove the previous newline, or add an explicit semicolon \';\' @ line 90, column 2.\\n   \\t{\\n    ^\\n\\n1 error\\n",\n  "exception" : "BadInputException",\n  "stacktrace" : [ "org.neo4j.server.plugin.gremlin.GremlinPlugin.executeScript(GremlinPlugin.java:88)", "java.lang.reflect.Method.invoke(Method.java:616)", "org.neo4j.server.plugins.PluginMethod.invoke(PluginMethod.java:57)", "org.neo4j.server.plugins.PluginManager.invoke(PluginManager.java:168)", "org.neo4j.server.rest.web.ExtensionService.invokeGraphDatabaseExtension(ExtensionService.java:300)", "org.neo4j.server.rest.web.ExtensionService.invokeGraphDatabaseExtension(ExtensionService.java:122)", "java.lang.reflect.Method.invoke(Method.java:616)" ]\n}')

The query within the function works on neo4j console.

espeed commented 12 years ago

what happens when you format it like this...?

def short() {
    return g.v(1234).outE.filter{
        return (it.pvalue > 0) || (it.correlation < 0);
    };
}
amergin commented 12 years ago

with a one-liner like you said it works. Furthermore, it seems that

return g.v(1234).outE.filter{

works but

return g.v(1234).outE.filter
{

does not. is this a bulbs-related issue? The point was that I should be able to able to define multi-line closures as I can in the console. I often have filter clauses that grow very long and they need to be kept readable by using line splits.

espeed commented 12 years ago

I'm not exactly sure what the rule is on that. Marko wrote Gremlin-Groovy so he may have a better idea of why that's true. I would post it to the Gremlin-Users group for clarification.

amergin commented 12 years ago

According to Marko, there Gremlin shouldn't have a problem with multi-line closures: https://groups.google.com/forum/#!topic/gremlin-users/3m_3Zl0ek6c .

Maybe Bulbs is somehow pushing the wrong kind of syntax of the script to REST API?

Care to comment?

espeed commented 12 years ago

Bulbs is passing the body of the script to Rexster, so Rexster is seeing this:

    return g.v(1234).outE.filter
    {
        return (it.pvalue > 0) ||
        (it.correlation < 0);
    };

Do these two versions behave differently?

    return g.v(1234).outE.filter{
        return (it.pvalue > 0) ||
        (it.correlation < 0);
    };

...and...

    return g.v(1234).outE.filter
    {
        return (it.pvalue > 0) || (it.correlation < 0);
    };
espeed commented 11 years ago

Closing -- assuming this has been resolved.