Forum OpenACS Development: callbacks and plain parameters

Collapse
Posted by Jim Lynch on
is there a known problem with callbacks in 5.2 where the formal parameter names are not getting into the appropriate stack frame?

specifically...

The definition:

ad_proc \
    -callback bug_tracker::bug__add_new_log_entry \
    {log_id user_id peeraddr context_id} \
    { allows subscribing code to add db items associated with new log entry } \
    -

An Implementation:

ad_proc \
    -callback bug_tracker::bug__add_new_log_entry \
    -impl action_elapsed_time \
    {log_id user_id peeraddr context_id} \
    { add an ipt and attach it to the log entry of the bug } \
    {
        ...
        ns_log notice "log_id $log_id user_id $user_id peeraddr $peeraddr context_id $context_id"
        ...
    }

The Hook or Call:

set bug__addnewentry_list \
    [callback bug_tracker::bug__add_new_log_entry \
        $bt_rev_id \
        $user_id \
        $peeraddr \
        $package_id] 

I'm getting the error "can't read "log_id": no such variable". Why? Doesn't this suggest a bug with parameters?

Collapse
Posted by Jim Lynch on
more of the error message:

    while executing
"ns_log notice "log_id $log_id user_id $user_id peeraddr $peeraddr context_id $context_id""
    (procedure "::callback::bug_tracker::bug__add_new_log_entry::impl::actio..." line 8)
    invoked from within
"::callback::bug_tracker::bug__add_new_log_entry::impl::action_elapsed_time 2090 500 172.18.1.2 1283"
Collapse
Posted by Lee Denison on
I've committed a fix on head which should solve this problem. It only shows up when a contract only has positional arguments. For a plain ad_proc with only positional arguments an arg parser is not created because the standard tcl proc command will happily parse positional arguments for us. For a callback however the implementation relies on the arg parser of the contract so we need to create it anyway.
Collapse
Posted by Jim Lynch on
Hi,

Here is a diff to 00-proc-procs.tcl of openacs-5.2.x which 
allows the callbacks to only have positional parameters:

===== CUT HERE =====
--- 00-proc-procs.tcl~  2005-07-21 05:11:16.000000000 -0700
+++ 00-proc-procs.tcl   2006-05-16 03:55:22.637411203 -0700
@@ -432,7 +432,7 @@
         # We are creating a callback implementation so we invoke the
         # arg parser of the contract proc
         uplevel [::list proc $proc_name_as_passed args "    ::callback::${callback}::contract__arg_parser\n${log_code}$code_block"]
-    } elseif { [llength $switches] == 0 } {
+    } elseif { $callback eq "" && [llength $switches] == 0 } {
         uplevel [::list proc $proc_name_as_passed $arg_list "${log_code}$code_block"]
     } else {
          set parser_code "    ::upvar args args\n"
===== CUT HERE =====
Collapse
Posted by Jim Lynch on
or, as discussed, to have ad_proc build an arg parser in the case of a callback with only positional parameters.
Collapse
Posted by Dave Bauer on
Jim

This looks pretty good, but I really like to see patches, especially for a core function like this, to include an automated test for 1) the original functionality, to prove it still works, 2) the new functionality to prove that it doesn't work without the patch, and does work as expected with the patch.

This greatly reduces the effort required by code reviewers to understand what your patch is doing, and is a good way to learn how to add testing into your development.

Collapse
Posted by Jim Lynch on
Dave,

To clarify my reasoning for exposing the patch, Lee Denison had committed this to HEAD earlier (with a few other changes, like ... eq ... replacing [string equal ... ...]). What I did was take his patch and remove everything but the one thing that did the job.

If I understand correctly, feature adds to 5.2 are frozen. My intent was not to change 5.2 as shipped, but rather to provide folks running 5.2 with a working callback functionality if they personally wanted it; if so, they would apply the patch and restart their server.

To clarify what the patch does, it can be seen by looking at the patch itself: the else clause of that structure causes an argument parser to be built. The change adds an additional condition which must be satisfied to -not- build an argument parser: the ad_proc must not be defining a callback.

Collapse
Posted by Jim Lynch on
Aside from which.... isn't there already tests for (1)? :)