Forum OpenACS Q&A: Re: Problems defining procs

Posted by ultra newb on
The util_memoize method both works and doesn't work. It works depending on the position of my proc within the file. If it is at the end, it doesn't work. If I move it up in the file (above some other memoized procs), it works.
Posted by Gustaf Neumann on
Can you specify what you mean precisely by "not working"?

i have just added proc mkt {} [list return hi] into a library file (in my case packages/xowiki/tcl/xowiki-procs.tcl) reloaded the file via acs-admin/apm and called the proc mkt via ds/shell, and it returns the expected result (i.e. "hi"). i see nothing wrong.

Posted by ultra newb on
From above (I guess it got lost in the wall of text):

Nothing in the error logs except the same error I get when I try to access the page that tests the proc - "name of proc" isn't a procedure. Seems as if the proc is not being defined. If I define it the "normal" way (where I can't hardcode info in the proc) it gets defined. If I do it the other way, it apparently doesn't.

To repeat, when I say it is "not working," when I call the web page which uses the proc, I get a "'name of proc' isn't a procedure" error (it doesn't literally say 'name of proc', it uses the actual name of the proc I am trying to define).

Also, to repeat, this is not with a package I am defining, nor an existing package. I am simply using the www directory for my web pages, and I am putting my custom procs in a "blah-procs" file in the tcl folder.

Repeating again, I got the util_memoize to work, but only if I put the proc in a certain location in the "blah-procs" file. If I put it in a different location, I get the same error.

If you guys don't experience any of these problems, and don't believe a bug exists, I'll chalk it up to the installation.


Posted by ultra newb on
Thanks for testing, Gustaf.
Posted by Ryan Gallimore on
You need to put your blah-procs file inside a package. Copy it to /packages/some-package/tcl/ and visit acs-admin/apm and reload that package.

See the documentation on Packages for more information.

Posted by Jeff Rogers on
Unless you're redefining commands for proc creation, it shouldn't matter which is defined first. Putting it in a different location in the same file makes it sound like something is erroring out in the middle of that file and preventing the rest of it from running. If you're not seeing any error messages in your log from startup, try adding a log message after each proc is defined in your source file, as well as at the beginning and end. If you only get some of the log messages then you can pinpoint where it stopped running (and hopefully why).

If you get all the log messages but still see only some of the procs defined, then you've got everyone baffled. If you could share your entire source file, maybe we could reproduce the issue.

Posted by ultra newb on
Okay, I am indeed getting errors in the log. Here is the relevant portion of the log:

[11/Jun/2011:16:47:14][1032.1992][-thread1992-] Error: tcl: source c:/aolserver/servers/openacs/tcl/exchange-procs.tcl failed: no connection
no connection
while executing
"ns_conn headers"
(procedure "ad_host" line 2)
invoked from within
(procedure "exch" line 2)
invoked from within
"exch MKT"
(procedure "mkt" line 1)
invoked from within
("eval" body line 1)
invoked from within
"eval $script"
invoked from within
"ns_cache eval util_memoize $script {
list $current_time [eval $script]
(procedure "util_memoize" line 20)
invoked from within
"util_memoize mkt"
(file "c:/aolserver/servers/openacs/tcl/exchange-procs.tcl" line 36)
invoked from within
"source $file"

Don't know what "no connection means." If the other poster above is correct, I should put my code in a package... correct? I didn't want to have to create one, but I will try and report back.

Thanks to all for continuing to help - this is a great community.

Posted by ultra newb on
Update: Created a package for everything. I still have the same problems with the package.

Here is the exchange-procs.tcl file:

proc ret x {return $x}

proc exch cmd {
set EXCH_HOST [ad_host]
set EXCH_PORT 9999

set socket [socket $EXCH_HOST $EXCH_PORT]
puts -nonewline $socket $cmd
flush $socket

set reply {}
while {[set line [string trim [gets $socket]]] != {}} {
lappend reply $line
close $socket
return $reply

proc libdir {} {return [get_server_root]/packages/acs-subsite/lib}
util_memoize libdir

proc mkt {} {return [lindex [list [lrange [lindex [exch MKT] 0] 1 end]] 0]}
util_memoize mkt

proc mktmin {} {
return [lindex [exch MKMIN,MKMAX] 0]

As stated previously, it depends on the postition of various procs as to whether this works or not. I had rearranged things and had everything working up until I added the last proc (mktmin), which caused it to blow up again.

Posted by Jeff Rogers on
The "no connection" error is telling you that you are trying to perform an operation (in this case, getting the "host" header from the current request) in a context where there is no current request - at startup.

Once an error is raised in a tcl file, nothing further in that file will get executed, including commands to define procs. That would explain why the proc is available if you define it early in the file but not at the end.

To get the name of the server you are on when there is no request, use [ns_info hostname], or could you just use "localhost"?

Posted by ultra newb on
This was indeed the problem! All problems have now been solved, including dynamically-defining a proc.

Also, apparently don't have to define a package.

Thanks to everyone, this was a big help.