Rocksolid Light

News from da outaworlds

mail  files  register  groups  login

Message-ID:  

BOFH excuse #117: the printer thinks its a router.


comp / comp.lang.tcl / Re: Proper way to split a string?

SubjectAuthor
* Proper way to split a string?Luc
+- Re: Proper way to split a string?Rich
+- Re: Proper way to split a string?Emiliano
`* Re: Proper way to split a string?Gerald Lester
 `* Re: Proper way to split a string?Luc
  `- Re: Proper way to split a string?Rich

1
Subject: Proper way to split a string?
From: Luc
Newsgroups: comp.lang.tcl
Organization: A noiseless patient Spider
Date: Tue, 17 Dec 2024 04:37 UTC
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: luc@sep.invalid (Luc)
Newsgroups: comp.lang.tcl
Subject: Proper way to split a string?
Date: Tue, 17 Dec 2024 01:37:49 -0300
Organization: A noiseless patient Spider
Lines: 40
Message-ID: <20241217013749.5e0897be@lud1.home>
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Injection-Date: Tue, 17 Dec 2024 05:37:50 +0100 (CET)
Injection-Info: dont-email.me; posting-host="f47be636d9297afaa4e0d79d9b92e427";
logging-data="1648502"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/z1W0JomsDpsnX/PeyvrKN6tBjS0lz1Ms="
Cancel-Lock: sha1:EfwXUSHNpSNyhOhIWzhg72pycIw=
View all headers

Howdy. I have this pop-up dialog that prompts for two pieces of
information: a name (arbitrary string) and a button that will
invoke a file browser so the user can select a file. Then:

bind $::SRw <Return> {set ::PINPUT "$pname|$pfile"}

then:

vwait ::PINPUT
catch {destroy $::SRw}
return $::PINPUT

It works.

But then I use the ::PINPUT variable, splitting it on the pipe |
symbol to identify the two pieces of information. And then I think,
what if the user uses the pipe symbol in $name?

OK, how about this:

bind $::SRw <Return> {set ::PINPUT "$pname::::::::::::::::$pfile"}

And then I think, what if the user's cat walks on the keyboard and
the user actually enters that kind of string?

OK, how about this:

bind $::SRw <Return> {set ::PINPUT "$pname|=MagicSeparator=|$pfile"}

And then I think, what if the user is possessed by Satan and actually
uses that Magic Separator in $name?

As unlikely as that is, I ask of you: what is the wise, serious,
professional way of handling that situation and making sure that
worse things won't happen at sea?

--
Luc
>>

Subject: Re: Proper way to split a string?
From: Rich
Newsgroups: comp.lang.tcl
Organization: A noiseless patient Spider
Date: Tue, 17 Dec 2024 05:05 UTC
References: 1
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: rich@example.invalid (Rich)
Newsgroups: comp.lang.tcl
Subject: Re: Proper way to split a string?
Date: Tue, 17 Dec 2024 05:05:04 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 24
Message-ID: <vjr0q0$1i1a9$4@dont-email.me>
References: <20241217013749.5e0897be@lud1.home>
Injection-Date: Tue, 17 Dec 2024 06:05:04 +0100 (CET)
Injection-Info: dont-email.me; posting-host="876264b18c00e4986a1fe1d9ed3feb32";
logging-data="1639753"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19tpiG53LX26vz+e/oa4ntm"
User-Agent: tin/2.6.1-20211226 ("Convalmore") (Linux/5.15.139 (x86_64))
Cancel-Lock: sha1:ThuBN8pTobU/rQJiMmfnc3CRp+4=
View all headers

Luc <luc@sep.invalid> wrote:
> As unlikely as that is, I ask of you: what is the wise, serious,
> professional way of handling that situation and making sure that
> worse things won't happen at sea?

If you really want both pieces in the same variable then use a proper
list:

bind $::SRw <Return> {set ::PINPUT [list $pname $pfile]}

Then you can access each piece with lindex 0 or lindex 1 (depending
upon which you want at the time) and Tcl will take care of making sure
the two pieces remain separate pieces.

Otherwise, just store them away as two separate variables:

bind $::SRw <Return> {
set ::PINPUT_name $pname
set ::PINPUT_file $pfile
}

Note, your example will likely not work because when the <Return>
binding runs, $pname and $pfile will not be variables in the global
scope, so adjust accordingly.

Subject: Re: Proper way to split a string?
From: Emiliano
Newsgroups: comp.lang.tcl
Organization: A noiseless patient Spider
Date: Sat, 21 Dec 2024 03:41 UTC
References: 1
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: emiliano@example.invalid (Emiliano)
Newsgroups: comp.lang.tcl
Subject: Re: Proper way to split a string?
Date: Sat, 21 Dec 2024 00:41:42 -0300
Organization: A noiseless patient Spider
Lines: 34
Message-ID: <20241221004142.8270d72a745f2a7513489c48@example.invalid>
References: <20241217013749.5e0897be@lud1.home>
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Injection-Date: Sat, 21 Dec 2024 04:41:43 +0100 (CET)
Injection-Info: dont-email.me; posting-host="6441a5da0578daf68cd5d253ff34d60c";
logging-data="4072248"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+KklZKETJWOVHC3pN4Q3TTk5pLBIHMsmI="
Cancel-Lock: sha1:ZBdeB05j0fseoyH3qyNA1jcMOk0=
X-Newsreader: Sylpheed 3.5.1 (GTK+ 2.24.32; i686-pc-linux-gnu)
View all headers

On Tue, 17 Dec 2024 01:37:49 -0300
Luc <luc@sep.invalid> wrote:

[snip]
> OK, how about this:
>
> bind $::SRw <Return> {set ::PINPUT "$pname::::::::::::::::$pfile"}

Incidentally, this wont work.

% set pname foo
foo
% set pfile bar
bar
% set ::PINPUT "$pname::::::::::::::::$pfile"
can't read "pname::::::::::::::::": no such variable

This is because there are two variable expansions in this expression:
one is ${pname::::::::::::::::} which is a variable in the (relative to
current scope) pname namespace with the with the empty string {} as
name (equivalent to [namespace eval pname {set {}}]) and the other is
$pfile. As the [namespace] documentation states, two or more colons are
namespace separators, so any number of colons > 2 are equivalent to "::".

Quoting the manual page:
"Extra colons in any separator part of a qualified name are ignored;
i.e. two or more colons are treated as a namespace separator.
A trailing :: in a qualified variable or command name refers to the
variable or command named {}."

Regards

--
Emiliano

Subject: Re: Proper way to split a string?
From: Gerald Lester
Newsgroups: comp.lang.tcl
Organization: fastusenet - www.fastusenet.org
Date: Sat, 21 Dec 2024 05:13 UTC
References: 1
Path: eternal-september.org!news.eternal-september.org!feeder3.eternal-september.org!usenet.blueworldhosting.com!diablo1.usenet.blueworldhosting.com!peer01.iad!feed-me.highwinds-media.com!news.highwinds-media.com!fx15.iad.POSTED!not-for-mail
MIME-Version: 1.0
User-Agent: Mozilla Thunderbird
Subject: Re: Proper way to split a string?
Newsgroups: comp.lang.tcl
References: <20241217013749.5e0897be@lud1.home>
Content-Language: en-US
From: Gerald.Lester@gmail.com (Gerald Lester)
In-Reply-To: <20241217013749.5e0897be@lud1.home>
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 7bit
Lines: 59
Message-ID: <c8s9P.33892$0O61.32415@fx15.iad>
X-Complaints-To: abuse@fastusenet.org
NNTP-Posting-Date: Sat, 21 Dec 2024 05:13:44 UTC
Organization: fastusenet - www.fastusenet.org
Date: Fri, 20 Dec 2024 23:13:44 -0600
X-Received-Bytes: 2320
View all headers

On 12/16/24 22:37, Luc wrote:
> Howdy. I have this pop-up dialog that prompts for two pieces of
> information: a name (arbitrary string) and a button that will
> invoke a file browser so the user can select a file. Then:
>
> bind $::SRw <Return> {set ::PINPUT "$pname|$pfile"}
>
> then:
>
> vwait ::PINPUT
> catch {destroy $::SRw}
> return $::PINPUT
>
> It works.
>
> But then I use the ::PINPUT variable, splitting it on the pipe |
> symbol to identify the two pieces of information. And then I think,
> what if the user uses the pipe symbol in $name?
>
> OK, how about this:
>
> bind $::SRw <Return> {set ::PINPUT "$pname::::::::::::::::$pfile"}
>
> And then I think, what if the user's cat walks on the keyboard and
> the user actually enters that kind of string?
>
> OK, how about this:
>
> bind $::SRw <Return> {set ::PINPUT "$pname|=MagicSeparator=|$pfile"}
>
> And then I think, what if the user is possessed by Satan and actually
> uses that Magic Separator in $name?
>
> As unlikely as that is, I ask of you: what is the wise, serious,
> professional way of handling that situation and making sure that
> worse things won't happen at sea?
> ]

Rich suggested making it a list. You can do that or make ::PINPUT an array:

set ::PINPUT(state) waiting
bind $::SRw <Return> {
set ::PINPUT(pname) $pname
set ::PINPUT(pname) $pfile
set ::PINPUT(state) done
}

then:

vwait ::PINPUT(state)
catch {destroy $::SRw}
return [array get ::PINPUT]

Where you go to use it, do:

array set resultArray $returnValue

Or use the dict command to access the pieces.

Subject: Re: Proper way to split a string?
From: Luc
Newsgroups: comp.lang.tcl
Organization: A noiseless patient Spider
Date: Sat, 21 Dec 2024 19:54 UTC
References: 1 2
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: luc@sep.invalid (Luc)
Newsgroups: comp.lang.tcl
Subject: Re: Proper way to split a string?
Date: Sat, 21 Dec 2024 16:54:27 -0300
Organization: A noiseless patient Spider
Lines: 37
Message-ID: <20241221165427.54f656fd@lud1.home>
References: <20241217013749.5e0897be@lud1.home>
<c8s9P.33892$0O61.32415@fx15.iad>
MIME-Version: 1.0
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
Injection-Date: Sat, 21 Dec 2024 20:54:28 +0100 (CET)
Injection-Info: dont-email.me; posting-host="03bf16982c8f347a6dd7b85c14553ecc";
logging-data="221426"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/CFadi2g++mzKFh6PpLjlHlQQYQb0IWWc="
Cancel-Lock: sha1:FQoarJM6lznFzIXCUbsozT3a9aQ=
View all headers

On Fri, 20 Dec 2024 23:13:44 -0600, Gerald Lester wrote:

>Rich suggested making it a list. You can do that or make ::PINPUT an array:
>
>set ::PINPUT(state) waiting
>bind $::SRw <Return> {
> set ::PINPUT(pname) $pname
> set ::PINPUT(pname) $pfile
> set ::PINPUT(state) done
>}
>
>then:
>
>vwait ::PINPUT(state)
>catch {destroy $::SRw}
>return [array get ::PINPUT]
>
>Where you go to use it, do:
>
>array set resultArray $returnValue
>
>Or use the dict command to access the pieces.
>
**************************

It's good to know that I was even wronger than I thought.

I have been using a list as Rich suggested, but the use of an array
is very interesting, rather Tcl-ish.

Thank you all for the education.

--
Luc
>>

Subject: Re: Proper way to split a string?
From: Rich
Newsgroups: comp.lang.tcl
Organization: A noiseless patient Spider
Date: Sat, 21 Dec 2024 21:12 UTC
References: 1 2 3
Path: eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail
From: rich@example.invalid (Rich)
Newsgroups: comp.lang.tcl
Subject: Re: Proper way to split a string?
Date: Sat, 21 Dec 2024 21:12:01 -0000 (UTC)
Organization: A noiseless patient Spider
Lines: 57
Message-ID: <vk7av1$7hb6$1@dont-email.me>
References: <20241217013749.5e0897be@lud1.home> <c8s9P.33892$0O61.32415@fx15.iad> <20241221165427.54f656fd@lud1.home>
Injection-Date: Sat, 21 Dec 2024 22:12:03 +0100 (CET)
Injection-Info: dont-email.me; posting-host="57b96e268859e9d5a95605f7e8b06a17";
logging-data="247142"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+DAgdUEF/GlrBA0VqVWe1g"
User-Agent: tin/2.6.1-20211226 ("Convalmore") (Linux/5.15.139 (x86_64))
Cancel-Lock: sha1:2EUx+Ow3Mfnrfr1T5bZsTQdijvw=
View all headers

Luc <luc@sep.invalid> wrote:
> On Fri, 20 Dec 2024 23:13:44 -0600, Gerald Lester wrote:
>
>>Rich suggested making it a list. You can do that or make ::PINPUT an array:
>>
>>set ::PINPUT(state) waiting
>>bind $::SRw <Return> {
>> set ::PINPUT(pname) $pname
>> set ::PINPUT(pname) $pfile
>> set ::PINPUT(state) done
>>}
>>
>>then:
>>
>>vwait ::PINPUT(state)
>>catch {destroy $::SRw}
>>return [array get ::PINPUT]
>>
>>Where you go to use it, do:
>>
>>array set resultArray $returnValue
>>
>>Or use the dict command to access the pieces.
>>
> **************************
>
> It's good to know that I was even wronger than I thought.
>
> I have been using a list as Rich suggested, but the use of an array
> is very interesting, rather Tcl-ish.

And array has the downside of you cannot directly pass an array into a
proc nor directly return an array from a proc [1].

Either of a list or a dict can be passed in and returned directly with
no further 'effort' needed on your part within your code.

A list gives you the data, but without any attached 'names', so you
have to remember that "index 2 is data value Y" elsewhere.

A dict gives you 'named values' (just like an array) so if you prefer
that method, then you can use a dict to 'return' the values out of a
proc, and they will have names just like with an array.

And, you can convert a dict to an array via "array set array_name
$dict_name". Converting an array to a dict works this way "set
dict_name [dict create {*}[array get array_name]]" or by just
'accessing' the list returned from [array get] with the [dict] command,
which will shimmer it into a dict. The explicit [dict create] method
does make it clear in your code that you are purposefully performing
the transform.

[1] Instead you have to do things like "array get name_of_array" to
return it, or pass in the name of the array and use upvar to access it.

1

rocksolid light 0.9.8
clearnet tor