Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

Check existense of object, without touching internal representation
I've encountered a following problem - I'm passing into procedure
optional parameter, which can have quite complex internal Tcl_Obj
representation (custom object type from my C extension).

This object is optional. Be it some simple Tcl object such as string,
list etc, I would use following code:

proc do_something {{object {}}} {
if {[string length $object]} {
# do something with object
} else {
# do something without object
}
}

Problem is that [string length] does conversion of object into string
representation. Its typePtr->name now is "string". And when I want to do
something with it, internal representation is constructed again from
string one, which can be quite time-consuming.

If it was Perl, I would use if (defined($object)) which would just check
if something is there, without even accessing its internals.

How to do the same thing in Tcl? Is there any standard Tcl command,
which allows to check whether function argument just contain something?

I'm afraid that using default value other than empty string wouldn't
help, because comparation would result in conversion of object into type
of second operand.

In this particular case using of special keyword args might help

proc do_something {args} {
if {[llength $args]} {
#do something with [lindex $args 0]
} else {
# do sometihnf without object
}
}

But more universal way is desirable.


--
"You, sir, are nothing but a pathetically lame salesdroid!
I fart in your general direction!"
-- Randseed on #Linux

Report this thread to moderator Post Follow-up to this message
Old Post
Victor Wagner
08-20-04 08:59 PM


Re: Check existense of object, without touching internal representation
The only way I can think of off the top of my head is:

proc do_something {args} {
switch -exact [llength $args] {
0 {
# it wasn't provided
set object {}
} 1 {
set object [lindex $args 0]
} default {
error "usage: do_something ?object?"
}
}
# ...
}

Hope that helps,
Rob Seeger

Victor Wagner wrote:
> I've encountered a following problem - I'm passing into procedure
> optional parameter, which can have quite complex internal Tcl_Obj
> representation (custom object type from my C extension).
>
> This object is optional. Be it some simple Tcl object such as string,
> list etc, I would use following code:
>
> proc do_something {{object {}}} {
> 	if {[string length $object]} {
> 		# do something with object
> 	} else {
> 		# do something without object
> 	}
> }
>
> Problem is that [string length] does conversion of object into string
> representation. Its typePtr->name now is "string". And when I want to do
> something with it, internal representation is constructed again from
> string one, which can be quite time-consuming.
>
> If it was Perl, I would use if (defined($object)) which would just check
> if something is there, without even accessing its internals.
>
> How to do the same thing in Tcl? Is there any standard Tcl command,
> which allows to check whether function argument just contain something?
>
> I'm afraid that using default value other than empty string wouldn't
> help, because comparation would result in conversion of object into type
> of second operand.
>
> In this particular case using of special keyword args might help
>
> proc do_something {args} {
> 	if {[llength $args]} {
> 		#do something with [lindex $args 0]
> 	} else {
> 		# do sometihnf without object
> 	}
> }
>
> But more universal way is desirable.
>
>


Report this thread to moderator Post Follow-up to this message
Old Post
Robert Seeger
08-21-04 01:56 AM


Re: Check existense of object, without touching internal representation
On Fri, 20 Aug 2004 20:16:26 GMT, Robert Seeger <robert@rkseeger.net>
wrote:

>The only way I can think of off the top of my head is:
>
>proc do_something {args} {
>     switch -exact [llength $args] {
>         0 {
>             # it wasn't provided
>             set object {}
>         } 1 {
>             set object [lindex $args 0]
>         } default {
>             error "usage: do_something ?object?"
>         }
>     }
>     # ...
>}
Or sort of combine your present solution with 'args', like
proc do_something {param1 param2 args} {
switch -exact [llength $args] {
0 {
# it wasn't provided
set object {}
} 1 {
set object [lindex $args 0]
} default {
error "usage: do_something param1 param2  ?object?"
}
}
# ...
}
HTH
Helmut Giese

Report this thread to moderator Post Follow-up to this message
Old Post
Helmut Giese
08-21-04 01:56 AM


Re: Check existense of object, without touching internal representation
vitus@45.free.net (Victor Wagner) writes:

> Problem is that [string length] does conversion of object into string
> representation. Its typePtr->name now is "string". And when I want to do
> something with it, internal representation is constructed again from
> string one, which can be quite time-consuming.

"shimmering"

> How to do the same thing in Tcl? Is there any standard Tcl command,
> which allows to check whether function argument just contain something?

No.  If it was given, then it contains something -- the zero-length
string.

There are two ways to do optional function parameters: with the
args list (which probably better suits you) or pairs of {arg default}.
To test if a parameter was given in $args, use [llength $args].
To test if a parameter was omitted, and given a default, then
you have to test for a recognizable default.  To avoid shimmering,
you should specify a default value with the same internal representation
as the argument it replaces, and a test that does not force a
different internal representation.

I guess there is a third way:

Instead of passing the value to the function, pass a variable name
(pass by reference).  Then you can use upvar to get a local variable
reference, and then use [info exists] to see if the parameter exists
or not.

Donald Arseneau                          asnd@triumf.ca

Report this thread to moderator Post Follow-up to this message
Old Post
Donald Arseneau
08-21-04 01:56 AM


Re: Check existense of object, without touching internal representation
Victor Wagner wrote:

> I've encountered a following problem - I'm passing into procedure
> optional parameter, which can have quite complex internal Tcl_Obj
> representation (custom object type from my C extension).
>
> This object is optional. Be it some simple Tcl object such as string,
> list etc, I would use following code:
>
> proc do_something {{object {}}} {
> if {[string length $object]} {
> # do something with object
> } else {
> # do something without object
> }
> }
>
> Problem is that [string length] does conversion of object into string
> representation. Its typePtr->name now is "string". And when I want to do
> something with it, internal representation is constructed again from
> string one, which can be quite time-consuming.
>
[snip]

I don't want to derail the discussion, but I'm curious why the construction
of a string from the internal representation should invalidate the internal
representation. It is sometimes the case that string->internal conversion
will want to invalidate the string representation (i.e. if different
strings could yield the same internal representation and you want to insure
that a canonical string representation is reconstructed). Perhaps the "C"
extension could be mended to not invalidate the internal rep when the
string rep is updated.

Andrew


Report this thread to moderator Post Follow-up to this message
Old Post
Andrew Mangogna
08-21-04 09:04 AM


Re: Check existense of object, without touching internal representation
Donald Arseneau wrote:
> There are two ways to do optional function parameters: with the
> args list (which probably better suits you) or pairs of {arg default}.
> To test if a parameter was given in $args, use [llength $args].
> To test if a parameter was omitted, and given a default, then
> you have to test for a recognizable default.  To avoid shimmering,
> you should specify a default value with the same internal representation
> as the argument it replaces, and a test that does not force a
> different internal representation.
>
> I guess there is a third way:
>
> Instead of passing the value to the function, pass a variable name
> (pass by reference).  Then you can use upvar to get a local variable
> reference, and then use [info exists] to see if the parameter exists
> or not.
>
> Donald Arseneau                          asnd@triumf.ca

There's a fourth way:

proc do_something {{object {}}} {
________if {[llength [info level 0]] > 1} {
________________# do something with object
________} else {
________________# do something without object
________}
}

This will allow you to really determine if an argument was specified, even
if it is exactly the same as the default value for the optional argument.

Schelte.
--
set Reply-To [string map {nospam schelte} $header(From)]


Report this thread to moderator Post Follow-up to this message
Old Post
Schelte Bron
08-22-04 09:06 PM


Re: Check existense of object, without touching internal representation
Schelte Bron <nospam@wanadoo.nl> writes:

> ________if {[llength [info level 0]] > 1} {

Niiiice.

Donald Arseneau                          asnd@triumf.ca

Report this thread to moderator Post Follow-up to this message
Old Post
Donald Arseneau
08-23-04 01:59 AM


Re: Check existense of object, without touching internal representation
Hehe, I was thinking the exact same thing. When I saw it, my first
thought was "omg, thats slick, why didn't I think of that". I've always
used args in situations like that and hated it because it I either have
to keep a usage error notice up to date, or the user will have no clue
what the args are unless they look at the source.

Rob Seeger

Donald Arseneau wrote:

> Schelte Bron <nospam@wanadoo.nl> writes:
>
> 
>
>
> Niiiice.
>
> Donald Arseneau                          asnd@triumf.ca


Report this thread to moderator Post Follow-up to this message
Old Post
Robert Seeger
08-23-04 01:59 AM


Re: Check existense of object, without touching internal representation

> There's a fourth way:
>
> proc do_something {{object {}}} {
>         if {[llength [info level 0]] > 1} {
>                 # do something with object
>         } else {
>                 # do something without object
>         }
> }
>
> This will allow you to really determine if an argument was specified, even
> if it is exactly the same as the default value for the optional argument.
>
> Schelte.

My try at this:
proc defaultvalues? {} {
expr {[llength [info args [lindex [info level 1] 0]]] -
([llength [info level 1]]-1)}
}

Trying it out:

% proc test {a {b 1} {c 2}} {puts [defaultvalues?]}
% test 1
2
% test 1 2
1
% test 1 2 3
0

Michael

Report this thread to moderator Post Follow-up to this message
Old Post
Michael Schlenker
08-23-04 01:59 AM


Re: Check existense of object, without touching internal representation
Andrew Mangogna wrote:
>Victor Wagner wrote: 
>
>I don't want to derail the discussion, but I'm curious why the construction
>of a string from the internal representation should invalidate the internal
>representation.

The problem is that many of the [string] subcommands
don't actually operate on the string representation!
Instead, they convert the UTF8-encoded string rep to
a UCS-2-based internal representation.

See generic/tclStringObj.c for all the details, but
the basic idea is that some operations ([string length],
[string range], a few others) are easier to implement and/or
faster with a fixed-length encoding than they are with a
variable-length one.


--Joe English

Report this thread to moderator Post Follow-up to this message
Old Post
Joe English
08-26-04 01:57 AM


Sponsored Links




Last Thread Next Thread Next
Pages (2): [1] 2 »
Search this forum -> 
Post New Thread

Tcl archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 01:15 PM.

 

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.