For Programmers: Free Programming Magazines  


Home > Archive > Tcl > September 2006 > extra character error









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author extra character error
zeeta6

2006-09-21, 7:07 pm

Hello,

I really hope that someone can find out the problem in the following
code. I'm new to tcl and this is pretty much one of my first programs.

<start>
set lConditional { [expr {1>0}] && [expr {2>0}] }


if {expr [$lConditional]}{
label .label1 -text "good!!"
grid .label1 }

</start>

Following is the error that I'm getting when running:

"extra characters after close-brace while executing

"if {expr [$lConditional]}{
label .label1 -text "good!!"
grid .label1 }"


What I'm basically tring to achieve is set a condition in a variable
and then later use it in the if statement. This makes it very easy and
clean as I'm generating the tickle script from VisualBasic 6.

Dennis LaBelle

2006-09-21, 7:07 pm

zeeta6 wrote:

> Hello,
>
> I really hope that someone can find out the problem in the following
> code. I'm new to tcl and this is pretty much one of my first programs.
>
> <start>
> set lConditional { [expr {1>0}] && [expr {2>0}] }
>
>
> if {expr [$lConditional]}{
> label .label1 -text "good!!"
> grid .label1 }
>
> </start>
>
> Following is the error that I'm getting when running:
>
> "extra characters after close-brace while executing
>
> "if {expr [$lConditional]}{
> label .label1 -text "good!!"
> grid .label1 }"
>
>
> What I'm basically tring to achieve is set a condition in a variable
> and then later use it in the if statement. This makes it very easy and
> clean as I'm generating the tickle script from VisualBasic 6.


You are missing a space between your close and open brackets on the if
statement. However, once you fix this problem you will notice another one
on the same line. The first line of the IF statement should be typed as:

if {[expr $lConditional]} {


naim

2006-09-21, 9:42 pm

Hi everybody..

I am a newbie in ns-2. I have succesfully finished installing ns2.26. The problem is, when i was trying to run any example from the file such as example.tcl, it has returned an error message such as "command not found". I have tried all differents kinds of command such as:

../ns example.tcl, ns example.tcl, $ns example.tcl, ns2.26 ns26 example.tcl

and many more. according to what i have learn so far, the code to simulate the script in ns2.26 is just "./ns <filename>"

am i right?? Is there any other command or i have type a wrong command? anybody can help me on the problem i am facing? thank you in advance for your help.
Donald Arseneau

2006-09-22, 4:22 am

"zeeta6" <bilalnadeem@gmail.com> writes:

> "extra characters after close-brace while executing
>
> "if {expr [$lConditional]}{

^
space between arguments "} {"

Theare a re lots of other problems with the program, stemming from
ecessive use of [expr ] and improper, or just strange, use of substitution.


> set lConditional { [expr {1>0}] && [expr {2>0}] }
> if {expr [$lConditional]}{


This will try to execute a command named " [expr {1>0}] && [expr {2>0}] ",
and there is none. You probably meant

if {expr "$lConditional"} {

But there is no need to nest expr commands within expressions, ir even
in the if-conditionals. This is just written normally:

if { 1>0 && 2>0 } {

If you really need to save the test as a string in a variable, then you write

set lConditional { 1>0 && 2>0 }
if $lConditional {

(without braces), but it is better to use a flag for deciding the conditional
rather than a varying string.



--
Donald Arseneau asnd@triumf.ca
Alan Anderson

2006-09-22, 4:22 am

Dennis LaBelle <labelled@nycap.rr.com> wrote:

> ...The first line of the IF statement should be typed as:
>
> if {[expr $lConditional]} {


Isn't the first argument of an if command automatically fed to expr
anyway? I'd just write it as:

if {$lConditional} {
Donal K. Fellows

2006-09-22, 4:22 am

Alan Anderson wrote:
> Isn't the first argument of an if command automatically fed to expr
> anyway? I'd just write it as:
> if {$lConditional} {


It's (effectively) fed in quoted form, so this would be correct:

if $lConditional {

but it's considered to be terrible style. Wrapping the {[expr ...]}
round it at least serves as a "watch out, I'm doing nasty stuff" marker!

Donal.
Donald Arseneau

2006-09-22, 8:01 am

Donald Arseneau <asnd@triumf.ca> writes:

>
> This will try to execute a command named " [expr {1>0}] && [expr {2>0}] ",
> and there is none. You probably meant
>
> if {expr "$lConditional"} {


Ack! Typo. I meant you meant

if { [expr "$lConditional"] } {

(or if { [expr $lConditional] } { )


> if $lConditional {
>
> (without braces), but it is better to use a flag for deciding the conditional
> rather than a varying string.


Donal feels the [expr ] is a warning of trickiness, whereas I feel
that lack of braces stands out. Anyway, I hope we both think that
strings for conditionals tends to beg for trouble.


--
Donald Arseneau asnd@triumf.ca
zeeta6

2006-09-22, 8:01 am

Thank you all for the nice replies. I agree saving the value ( true or
false ) in the lConditional instead. Here's what I've done:


set lConditional1 [expr 1>0 && 2>0]
set lConditional2 [expr -1<0]
set lConditional [expr $lConditional1 && $lConditional2]

if $lConditional {
label .label1 -text "good!!"
grid .label1 }

It's working good now. I would really appreciate any inputs to improve
the above code.

Thanks



Donald Arseneau wrote:
> Donald Arseneau <asnd@triumf.ca> writes:
>
>
> Ack! Typo. I meant you meant
>
> if { [expr "$lConditional"] } {
>
> (or if { [expr $lConditional] } { )
>
>
>
> Donal feels the [expr ] is a warning of trickiness, whereas I feel
> that lack of braces stands out. Anyway, I hope we both think that
> strings for conditionals tends to beg for trouble.
>
>
> --
> Donald Arseneau asnd@triumf.ca


Bryan Oakley

2006-09-22, 7:03 pm

zeeta6 wrote:
> Thank you all for the nice replies. I agree saving the value ( true or
> false ) in the lConditional instead. Here's what I've done:
>
>
> set lConditional1 [expr 1>0 && 2>0]


Are you aware the above will immediately set lConditional1 to the value 1?

> set lConditional2 [expr -1<0]


....and this will set lConditional2 to the value 1?

> set lConditional [expr $lConditional1 && $lConditional2]


.... and this will set lConditional to the value 1?


> if $lConditional {


.... and thus the above is equivalent to:

if 1 {

> label .label1 -text "good!!"
> grid .label1 }
>
> It's working good now. I would really appreciate any inputs to improve
> the above code.


How about :

set lConditional1 {1>0 && 2>0}
set lConditional2 {-1<0}
if "($lConditional1) && ($lConditional2)" {...}

I think that's more in the spirit of what you're trying to do. As I
understand it, you're wanting to store conditions in variables, and use
those stored conditions in an if statement.

It's hard for us to give a definitive answer because you're asking a
somewhat complex question with not enough details. For example, where
you have "-1<0", is that really an expression you're wanting to use or
is your real world data more complex? Can these initial expressions have
variable names or references to tcl procedures? And so on...

When it all boils down, it's a matter of quoting. The if statement is
defined as "if <expression> ...", and <expression> be be expressed any
way you want. That's the beauty of Tcl. It means you can do things like:

if $variable ...
if [someCommand] ...
if {some hard-coded expression} ...

Tcl doesn't care. It takes the first argument *after it does it's own
normal round of substitution* and passes it to the if command. The if
command then does a *second* round of substitution. So, your job is to
figure out how to give the if command something reasonable after tcl's
normal pass at substitution.

Traditionally (and not coincidentally, the most efficient and
recommended way) to do this is to enclose a hard-coded expression in
curly braces, knowing that expr will do it's own round of substitution
on what it is given. The curly braces guarantee that what the expression
parser sees is exactly what you typed.

99.99% of the time, avoiding this double substitution is a Good Thing.
You have stumbled into that other 0.01% of the time when you want double
substitution. Namely, you have an expression in a variable rather than
hard-coded into your code.

So, think like the interpreter for a second and try to see what will
actually be handed off to the if command after tcl does its normal round
of substitution. Be mindful of the effects of curly braces and quotes up
to and including the call to the if command. At each step ask yourself
"do I want variables substituted now?".
suchenwi

2006-09-22, 7:03 pm


zeeta6 schrieb:
> set lConditional1 [expr 1>0 && 2>0]
> set lConditional2 [expr -1<0]
> set lConditional [expr $lConditional1 && $lConditional2]


Now you can (and should) brace your expressions. When variables are
involved:
set lConditional [expr {$lConditional1 && $lConditional2}]

> if $lConditional {

Here again (saves some time as the boolean value doesn't have to be
parsed again):
if {$lConditional} {



> label .label1 -text "good!!"
> grid .label1 }


zeeta6

2006-09-22, 7:03 pm


Bryan Oakley wrote:
> How about :
>
> set lConditional1 {1>0 && 2>0}
> set lConditional2 {-1<0}
> if "($lConditional1) && ($lConditional2)" {...}
>
> I think that's more in the spirit of what you're trying to do. As I
> understand it, you're wanting to store conditions in variables, and use
> those stored conditions in an if statement.
>
> It's hard for us to give a definitive answer because you're asking a
> somewhat complex question with not enough details. For example, where
> you have "-1<0", is that really an expression you're wanting to use or
> is your real world data more complex? Can these initial expressions have
> variable names or references to tcl procedures? And so on...


> When it all boils down, it's a matter of quoting. The if statement is
> defined as "if <expression> ...", and <expression> be be expressed any
> way you want. That's the beauty of Tcl. It means you can do things like:
>
> if $variable ...
> if [someCommand] ...
> if {some hard-coded expression} ...
>
> Tcl doesn't care. It takes the first argument *after it does it's own
> normal round of substitution* and passes it to the if command. The if
> command then does a *second* round of substitution. So, your job is to
> figure out how to give the if command something reasonable after tcl's
> normal pass at substitution.
>
> Traditionally (and not coincidentally, the most efficient and
> recommended way) to do this is to enclose a hard-coded expression in
> curly braces, knowing that expr will do it's own round of substitution
> on what it is given. The curly braces guarantee that what the expression
> parser sees is exactly what you typed.
>
> 99.99% of the time, avoiding this double substitution is a Good Thing.
> You have stumbled into that other 0.01% of the time when you want double
> substitution. Namely, you have an expression in a variable rather than
> hard-coded into your code.
>
> So, think like the interpreter for a second and try to see what will
> actually be handed off to the if command after tcl does its normal round
> of substitution. Be mindful of the effects of curly braces and quotes up
> to and including the call to the if command. At each step ask yourself
> "do I want variables substituted now?".



The 1>0, 2>0 are examples. what I really have is a method
("compareStrings") which returns either 1 or 0. I'm not using the
"string match -nocase" directly as I trim/edit the strings first in
compareStrings before passing them to "string match -nocase"

Therefore, what I really have is:

compareStrings "string1" "string2"

The tcl script is generated based on what the user has selected on an
html form. My dll takes these selections and generates the tcl file
(which is consumed by a third-party dll)

Therefore, what I could potentially have in lConditional is:

compareStrings "string" "string1" || compareString "string" "string2"
|| ....

so:

----------------------------
set lConditional1 {[compareStrings "string" "string1"] ||
[compareStrings "string" "string2"] || ....}

#(for another set of options)
set lConditional2 {[compareStrings "string" "string1"] ||
[compareStrings "string" "string2"] || ....}

if "($lConditional1) && ($lConditional2)" { .. }
-----------------------------

would the above work?

Thanks for the detailed email. Really helpful towards learning this
very intersting language.

Bryan Oakley

2006-09-22, 7:03 pm

zeeta6 wrote:

> so:
>
> ----------------------------
> set lConditional1 {[compareStrings "string" "string1"] ||
> [compareStrings "string" "string2"] || ....}
>
> #(for another set of options)
> set lConditional2 {[compareStrings "string" "string1"] ||
> [compareStrings "string" "string2"] || ....}
>
> if "($lConditional1) && ($lConditional2)" { .. }
> -----------------------------
>
> would the above work?
>


I think so. Let'er rip and tell us what happens.
Ralf Fassel

2006-09-22, 7:03 pm

* "zeeta6" <bilalnadeem@gmail.com>
| The tcl script is generated based on what the user has selected on an
| html form. My dll takes these selections and generates the tcl file
| (which is consumed by a third-party dll)
|
| Therefore, what I could potentially have in lConditional is:
|
| compareStrings "string" "string1" || compareString "string" "string2"
| || ....
|
| so:
|
| ----------------------------
| set lConditional1 {[compareStrings "string" "string1"] ||
| [compareStrings "string" "string2"] || ....}
|
| #(for another set of options)
| set lConditional2 {[compareStrings "string" "string1"] ||
| [compareStrings "string" "string2"] || ....}
|
| if "($lConditional1) && ($lConditional2)" { .. }
| -----------------------------
|
| would the above work?

If you completely control what is in the strings: yes, it may work.
(But then, why do you have to modify the strings in that case?)

If any 'string' is modifiable by the user directly (eg, by a forms
text field or something like this), then it most probably will fail if
the user enters any TCL-special character like " (double-quote) or [],
since that will break the syntax of the generated code, or even worse
will execute arbitrary code.

R'
zeeta6

2006-09-22, 7:03 pm


Ralf Fassel wrote:
> If you completely control what is in the strings: yes, it may work.
> (But then, why do you have to modify the strings in that case?)


I have complete control over the strings. But the string to which I'm
comparing these selected options with is not in my hands;its provided
by the third party dll. That string needs to be "cleaned' up.

Thanks for the heads-up.

Just for the info (if you guys are wondering how I'm able to write this
tcl in the first place with my limited knowledege of tcl ): the tcl
file comes with the third-party dll; i'm just modifying a portiong of
it.

Joe English

2006-09-22, 7:03 pm

zeeta6 wrote:
>Thank you all for the nice replies. I agree saving the value ( true or
>false ) in the lConditional instead. Here's what I've done:
>
>
>set lConditional1 [expr 1>0 && 2>0]
>set lConditional2 [expr -1<0]
>set lConditional [expr $lConditional1 && $lConditional2]
>
>if $lConditional {
>label .label1 -text "good!!"
>grid .label1 }
>
>It's working good now. I would really appreciate any inputs to improve
>the above code.


I would probably write this as:

if {(1>0 && 2>0) && (-1<0)} {
grid [label .label1 -text "Good!"]
}

*Actually*, since 1>0 && 2>0 && -1<0, the [if] clause always
succeeds, and this can be rewritten as:

grid [label .label1 -text "Good!"]

But presumably "1>0" etc. were just meant as placeholders
for the actual tests. So the only suggestion I have is
"always brace your exprs":

set lConditional1 [expr {1>0 && 2>0}]
set lConditional2 [expr {-1<0}]
set lConditional [expr {$lConditional1 && $lConditional2}]

if {$lConditional} {
[...]
}


--Joe English
Cameron Laird

2006-09-22, 7:03 pm

In article <pySQg.5150$7I1.2043@newssvr27.news.prodigy.net>,
Bryan Oakley <oakley@bardo.clearlight.com> wrote:
Donald Arseneau

2006-09-22, 10:01 pm

Bryan Oakley <oakley@bardo.clearlight.com> writes:

> zeeta6 wrote:
>
> Are you aware the above will immediately set lConditional1 to the value 1?


I would think so, given what he said. One would need to see the
program in context to judge how much "trickiness" or "unusual style"
is really needed.


--
Donald Arseneau asnd@triumf.ca
walton.paul@gmail.com

2006-09-24, 7:03 pm

What you have probably works, but this is more readable and
understandable, and doesn't need any fancy quoting:

if { [compareStrings $string1 $string2] || [compareStrings $string3
$string4] } {
if { [compareStrings $string5 $string6] || [compareStrings $string7
$string8] } {
...
}
}


If you really need the results of each comparison stored in a variable,
then I'd do:

set comparison1 [compareStrings $string1 $string2]
set comparison2 [compareStrings $string3 $string4]
set comparison3 [compareStrings $string5 $string6]
set comparison4 [compareStrings $string7 $string8]

If { ($comparison1 || $comparison2) && ($comparison3 || $comparison4)
} {
...
}

zeeta6 wrote:
> Bryan Oakley wrote:
>
>
>
> The 1>0, 2>0 are examples. what I really have is a method
> ("compareStrings") which returns either 1 or 0. I'm not using the
> "string match -nocase" directly as I trim/edit the strings first in
> compareStrings before passing them to "string match -nocase"
>
> Therefore, what I really have is:
>
> compareStrings "string1" "string2"
>
> The tcl script is generated based on what the user has selected on an
> html form. My dll takes these selections and generates the tcl file
> (which is consumed by a third-party dll)
>
> Therefore, what I could potentially have in lConditional is:
>
> compareStrings "string" "string1" || compareString "string" "string2"
> || ....
>
> so:
>
> ----------------------------
> set lConditional1 {[compareStrings "string" "string1"] ||
> [compareStrings "string" "string2"] || ....}
>
> #(for another set of options)
> set lConditional2 {[compareStrings "string" "string1"] ||
> [compareStrings "string" "string2"] || ....}
>
> if "($lConditional1) && ($lConditional2)" { .. }
> -----------------------------
>
> would the above work?
>
> Thanks for the detailed email. Really helpful towards learning this
> very intersting language.


Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com