I'm just trying my hand at writing my first tclpd library, 'tclfile', which is basically all of the individual subcommands of Tcl's 'file' command broken out as separate objects. This has given rise to a couple questions/comments:
- do I need to use proc+ or can I just use proc?
- it seems like the 'constructor' proc is the same as Pd's setup() function. If so, I think it should also be called 'setup'.
- is there an 0_anything/A_GIMME proc that can be used?
- multi-level namespaces to represent library and classname? Something like tclfile/mkdir would be tclfile::mkdir and have tclfile::mkdir::constructor.
.hc
----------------------------------------------------------------------------
I spent 33 years and four months in active military service and during that period I spent most of my time as a high class muscle man for Big Business, for Wall Street and the bankers. - General Smedley Butler
Il 07/11/2011 23:25, Hans-Christoph Steiner ha scritto:
I'm just trying my hand at writing my first tclpd library, 'tclfile', which is basically all of the individual subcommands of Tcl's 'file' command broken out as separate objects.
cheers!
This has given rise to a couple questions/comments:
- do I need to use proc+ or can I just use proc?
proc+ is defined in tclpd.tcl as follows:
proc proc+ {name arglist body} { set body2 [concat "global _;" [regsub -all @(\$?[\w\?]+) $body _($self:\1)]] uplevel #0 [list proc $name $arglist $body2] }
it allows you to have per instance ($self) object variables, like you usually have fields in the t_yourobject struct when coding externals in C (always have the first method argument called 'self'!)
- it seems like the 'constructor' proc is the same as Pd's setup() function. If so, I think it should also be called 'setup'.
it is not the setup function. maybe it is the _new() function
- is there an 0_anything/A_GIMME proc that can be used?
yes check examples/dynreceive.tcl
- multi-level namespaces to represent library and classname? Something like tclfile/mkdir would be tclfile::mkdir and have tclfile::mkdir::constructor.
didn't think of that, and right now it is not possible (the calling mechanism is hardcoded in c as ::<classname>::method)
.hc
I spent 33 years and four months in active military service and during that period I spent most of my time as a high class muscle man for Big Business, for Wall Street and the bankers. - General Smedley Butler
On Nov 7, 2011, at 5:43 PM, mescalinum@gmail.com wrote:
Il 07/11/2011 23:25, Hans-Christoph Steiner ha scritto:
I'm just trying my hand at writing my first tclpd library, 'tclfile', which is basically all of the individual subcommands of Tcl's 'file' command broken out as separate objects.
cheers!
This has given rise to a couple questions/comments:
- do I need to use proc+ or can I just use proc?
proc+ is defined in tclpd.tcl as follows:
proc proc+ {name arglist body} { set body2 [concat "global _;" [regsub -all @(\$?[\w\?]+) $body _($self:\1)]] uplevel #0 [list proc $name $arglist $body2] }
it allows you to have per instance ($self) object variables, like you usually have fields in the t_yourobject struct when coding externals in C (always have the first method argument called 'self'!)
- it seems like the 'constructor' proc is the same as Pd's setup() function. If so, I think it should also be called 'setup'.
it is not the setup function. maybe it is the _new() function
Ah right, yes, outlet creation is done in _new mostly. It would be nice to have tclpd use the same function names as Pd as much as possible because then the Pd docs like the Externals HOWTO will then also apply to Tclpd. free() is another name instead of destructor.
- is there an 0_anything/A_GIMME proc that can be used?
yes check examples/dynreceive.tcl
- multi-level namespaces to represent library and classname? Something like tclfile/mkdir would be tclfile::mkdir and have tclfile::mkdir::constructor.
didn't think of that, and right now it is not possible (the calling mechanism is hardcoded in c as ::<classname>::method)
I can imagine that for an full library written with tclpd, there would be shared code between the objects. That would then be in the ::tclfile namespace. Then each object would have a sub-namespace, i.e. ::tclfile::mkdir This will also make name collisions easier to avoid. There could be multiple libs with objects called 'mkdir'. I was thinking, the pd::class proc could just take the final piece of the namespaces as the object name
I have another question: with proc+ 0_symbol I seem to get "{symbol blah}" as $args. That's really hard to work with, how about making 0_symbol $args just be the symbol itself, i.e. "blah". This is what I had to do to get it to work:
set @filename [lindex {*}$args 1]
Also, I couldn't figure out how to output a float to the outlet, my attempt creates a message that is "float 1" but not a float:
pd::outlet $self 0 [list float [file exists $@filename]]
Here's my start of a 'tclfile' lib: http://pure-data.svn.sourceforge.net/viewvc/pure-data/trunk/externals/tclfil...
.hc
----------------------------------------------------------------------------
If you are not part of the solution, you are part of the problem.
Il 08/11/2011 04:10, Hans-Christoph Steiner ha scritto:
I can imagine that for an full library written with tclpd, there would be shared code between the objects.
tcl has a package system for that. (package provide / require)
I have another question: with proc+ 0_symbol I seem to get "{symbol blah}" as $args. That's really hard to work with, how about making 0_symbol $args just be the symbol itself, i.e. "blah". This is what I had to do to get it to work:
set @filename [lindex {*}$args 1]
pd lists (that is: atom lists) are just plain (tcl) lists of atoms. pd atoms in tcl are represented as {selector value}, for example {float 42} or {symbol blah}.
there are a couple of procs in tclpdlib for simplifying that.
for example you should use:
set @filename [pd::arg 0]
(I commited this fix for you). If you want full control over input, here's an example:
set atom0 [lindex $args 0]
set selector [lindex $atom0 0] set value [lindex $atom0 1]
if {$selector ne "symbol"} { return -code error "first argument must be a symbol!" }
# ...
by the way, for requiring a specific selector, you can just use:
set symbol0 [pd::arg 0 symbol]
Also, I couldn't figure out how to output a float to the outlet, my attempt creates a message that is "float 1" but not a float:
pd::outlet $self 0 [list float [file exists $@filename]]
wrong. the signature of pd::outlet is:
proc outlet {self n sel args} { ... }
so you should call:
pd::outlet $self $outlet_num list $list
for outputting a list, or in your case:
pd::outlet $self 0 float [file exists $@filename]
for outputting a float (I commited this fix as well)
bye