Let's see if revision 764992 solves the problem.
-Adrian
David E Jones wrote:
Avoiding declaration of variables was actually one of the goals of the
simple-methods, just like it is for most "scripting" languages (as
opposed to compiled languages).
I have no problem with the proposed attribute/etc, but it would be nice
to find a less cumbersome alternative... :)
-David
On Apr 14, 2009, at 3:19 PM, Adrian Crum wrote:
David,
Thanks for the reply!
I don't like the prefixing either, that's why I suggested the new
attribute values. To me, that makes the OFBiz scripting more like
other script engines - you can't use a variable unless it is declared.
One clarification that needs to be made though, in UEL the [] and .
operators don't determine whether the referenced object is a List or a
Map. UEL expressions can use ${object.property} or ${object[property]}
- there are no rules on the object's data type. The object data type
could be a List, a Map, or an arbitrary Object. The property could be
a List index, a Map key, or an Object method name. In UEL, the
object's data type determines how the property is used.
I'll continue to tinker with the auto-vivify code and see if I can
come up with a better solution. In the meantime, I'd still like to get
comments on the new attribute values.
-Adrian
David E Jones wrote:
Thanks for writing about this Adrian. I played with this a bit
yesterday after seeing your messages and the issue about the income
statement.
The main point that I think is important is that it is a WAY better
approach to use the natural data instead of trying to prefix it, as
that is pretty error prone since ALL code (even outside of
simple-methods for some code) has to be changed.
So anyway, trying to use a UEL syntax that supports this with things
like: theMap["${foo.bar}"] does work well for reading no matter what
"foo.bar" evaluates to (even a number), but like you said for the
auto-vivify o the Map the square-brace ([]) syntax means a list and
so a List is created instead of a Map.
The funny thing about the above is that even if you put a number in
quotes it evaluates to a number and not a String, and that causes the
auto-vivify to create a list instead of a Map for the square braces
([]). If we could do something about that it would be nice.
Another thing I'm considering is: let's just have the *Entity Engine*
prefix all generated keys so things in the database and other places
have a character first letter. That's easy to do with a single
attribute on the delegator element in the entityengine.xml file.
Along with that we'd have to change the current demo data to do this
as well.
It would still be nice to do something more about the Map auto-vivify
issue as it is much cleaner to treat things like data instead of like
a variable name. What I propose above is just a work-around, and not
the best option IMO... requiring identifiers to not be a number is a
bit of a bad thing...
-David
On Apr 14, 2009, at 12:38 PM, Adrian Crum wrote:
As many of you know, the introduction of the Uniform Expression
Language into the framework caused some backward compatibility
problems - specifically with IDs being used as Map keys. I tried to
accommodate that with a couple of bits of code, but there are still
some issues.
There have been suggestions on the mailing list for workarounds, but
not all of them work, nor do they work all the time. I don't want to
hack up the UEL library further, because its my viewpoint that OFBiz
should conform to existing standards, not twist existing standards
to conform to OFBiz.
The crux of the main problem is the implementation of auto-vivify
that I added to the UEL. Using the following code as an example:
<set field="someVar[someEntity.someId]" value="Hello World!"/>
If someVar was not previously defined, the auto-vivify code tries to
guess what data type someVar is supposed to be. If someEntity.someId
evaluates to an integer, the code assumes it is an index and creates
a List, otherwise it creates a Map. This works fine in most cases.
The problem comes when someEntity.someId evaluates to an integer
(most IDs are integers) and the developer intended someVar to be a
Map, not a List. There needs to be a way to create and empty Map in
those cases.
I believe the best solution is to modify the <set> element to allow
the creation of an empty Map or List. This will remove the ambiguity
and solve the problem - without further modifying UEL.
I modified my local copy to allow the creation of an empty Map:
<set field="someVar" type="NewMap"/>
<set field="someVar[someEntity.someId]" value="Hello World!"/>
and it works great.
So, the bottom line is, I would like to add "NewMap" and "NewList"
to the <set> element type attribute. What do you think?
-Adrian