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

Reply via email to