Ed Leafe wrote:
> On Nov 30, 2006, at 9:58 AM, Ed Leafe wrote:
>
>> You know, I hadn't played with this in a while, but now that I'm
>> looking at the code again, I can see a way to add automatic
>> references to the cursor and bizobj that 'owns' a particular data set
>> so that you could easily use methods of those two objects. I think
>> I'll add them now!
>
> Done. Boy, that was a lot easier than I thought. OK, so now you can
> create complex functions as methods in your bizobj, and then apply
> those to a field in the data set using:
>
> biz.replace("myField", "self.Bizobj.complexMethod(myField)")
>
Bunch of I-thinks - tell me what you think. :)
I think you are leaning on strings too much. It seems more pythonic to use
references and */**parms and lists and tupals and oh my! all that stuff.
> biz.replace("myField", "self.Bizobj.complexMethod(myField)")
I don't think that completely solves the problem. the problem is you want to
evaluate an expression in a different scope (or namespace?) that where the
function and maybe parameters are defined. ('maybe parameters' because you may
want to reference fields in other tables, or local vars.)
I think there can be a way of doing this that would let you pass the function
(an object reference to it, not the name) and arguments separately. so that it
looks like this:
biz.replace("myField", (someComplexStuff, ('myField') ) )
What comes next is related to this problem, may lend it self, or not. seems
like
now is a good time to bring it up:
What sort of support is there for this kind of thing in VFP:
h=sqlConnect( "nw", "sa", "foo" )
x=1
s="select * from Territories where RegionID=?x"
sqlExec( h, s )
For those that don't know: some VFP/Odbc interaction occurs and this is what
gets sent to the server (as displayed by MsSql Profiler)
exec sp_executesql N'select * from Territories where [EMAIL PROTECTED] ', N'@P1
float', 1.000000000000000e+000
x can be any VFP expression (vfp, not the back end syntax) and is evaluated in
the scope of the sqlExec(). It is nice, but the scope thing causes problems if
you define the query/parameters in once scope and the sqlexec() is wrapped in
some lower scope.
Here is my VFP solution to that:
http://fox.wikis.com/wc.dll?Wiki~SptParameters~VFP
So back to Python and Dabo:
I don't think you should have to add the function to the BO (biz object.) I
think the UI layer (either a hardcoded form or messing around with data
interactively) should be able to define a function and pass that to biz.replace
as part of a generic python expression.
Here is why: a hard coded form will have knowledge of the expression it is
trying to construct. in the above VFP example the expression is RegionID=1.
If there was a form, the form would have the words "Enter Region ID" and a
place
for the user to enter a RegionID value. The form has concrete references to
the
FieldName and value. I don't think the BO should also have to have concrete
references to the same thing.
The reason I specify python as the type of expression is two reasons: 1. I
don't
want anyone thinking that if the UI is written in perl that I should be able to
pass a perl expression. 2. I do want to be able to pass complex expressions,
including calls to functions I have written, and *values I have defined in the
UI layer*. This does bring up the problem of referencing BO.values (fields)
only I think it is easily solved by using the syntax/notation/qualification
that
is used in the UI layer. That may seem awkward, like adding a redundant step,
but I think the added flexibility is worth it. in VFP, the 'solution' to this
problem is the 'current work area' and the 'select <alias>' command. I don't
want to see that flavor of solution. It is only really useful when you are
doing things interactively, to save some keystrokes. I think short var names
will solve the keystroke problem.
Now for implementation:
From some file that has no header, so I can't cut/paste it. (how about some
headers?)
def replace(self, field, valOrExpr, scope=None):
"""Replaces the value of the specified field with the given
value
or expression. All records matching the scope are affected; if
no scope is specified, all records are affected.
'valOrExpr' will be treated as a literal value, unless it is
prefixed
with an equals sign. All expressions will therefore be a string
beginning with '='. Literals can be of any type.
Nooooo!!!!! you don't need to invent a new '=f(x)' syntax, or steel it from
VFP's annoying property sheet. values are expressions, so why not make
everything an expression?
Good to see scope has no definition, so we can change it to whatever is best an
no one can complain that it doesn't work right :)
if eval(scope):
I think that should just be
if scope:
I don't think we need to embed code in strings like we did in VFP. Not here
anyway.
These two lines seem awkward:
expr = "rec['%s'] = %s" % (field, valOrExpr)
exec(expr)
how about
rec[field] = eval( valOrExpr )
I am trying to figure out how to pass in an expression as an.. um... expression
object? I think the line of code in this method should simply be rec[field] =
Expr and Expr can either be a reference to a 'constant', a reference to a
function, or an expression in some other... namespace? (cuz scope is going to
be an issue)
>> help(eval)
Help on built-in function eval in module __builtin__:
eval(...)
eval(source[, globals[, locals]]) -> value
Evaluate the source in the context of globals and locals.
The source may be a string representing a Python expression
or a code object as returned by compile().
The globals must be a dictionary and locals can be any mappping,
defaulting to the current globals and locals.
If only globals is given, locals defaults to it.
OK, so scope is somehow addressed.
final thought: I think some separate code should be written to address working
interactively vs concrete application code. and the interactive helpers should
call the more 'cumbersome' methods. and by 'cumbersome' i mean when you are
working interactively, not doing production coding.
Carl K
_______________________________________________
Post Messages to: [email protected]
Subscription Maintenance: http://leafe.com/mailman/listinfo/dabo-users