Forum OpenACS Q&A: Re: namespace procs and the query dispatcher

Collapse
Posted by Roberto Mello on
Okay, since nobody replied, I went digging through the code.

It seems the ad_proc code that deals with namespaces is broken. The code does this:

    # (SDW - OpenACS). If proc_name is being defined inside a namespace, we
    # want to use the fully qualified name. Except for actually defining the
    # proc where we want to use the name as passed to us. We always set
    # proc_name_as_passed and conditionally make proc_name fully qualified
    # if we were called from inside a namespace eval.

    set proc_name_as_passed $proc_name
    set proc_namespace [uplevel {::namespace current}]
    if { $proc_namespace != "::" } {
        regsub {^::} $proc_namespace {} proc_namespace
        set proc_name "${proc_namespace}::${proc_name}"
    }

The problem with this is that it relies on a call to uplevel {::namespace current}, which doesn't return correctly when the procedure is not physically within a namespace block.

The problem only happens for procedures declared like this:

namespace eval foo {}

ad_proc -public ::foo::bar {}

In these cases the uplevel call returns "::" as the namespace (instead of ::foo), which screws up ad_proc, and consequently the QD, which relies on the ad_proc caching.

I'm looking into how to fix it.
-Roberto

Collapse
Posted by Dan Wickstrom on
I know ad_proc was modified at one point early on to handle both cases, so unless the changes got backed out somehow, I don't think that's the problem.  I know the templating system and cms have namespaces declared with the second form, and it's not a problem.
Collapse
Posted by Roberto Mello on
No, the templating system and CMS do not have procs declared like the second form. The problem was in ad_proc not handling the proc declaration with leading "::", not in the namespace declaration.

The leading :: tell Tcl that that proc goes into the global namespace. Templating and CMS do not have the leading ::

ad_proc -public template::form { command args } {

So the problem wasn't happening. The leading :: is not required in most cases (there's no occurrence of that form anywhere in the toolkit) but not allowing for it is broken.

That is fixed now.

-Roberto