Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

lmap: add to each list element fix string

51 views
Skip to first unread message

Harald Oehlmann

unread,
Sep 27, 2018, 2:49:26 PM9/27/18
to
I want to add a fix string to each list element.

May I use lmap ? What is the right body command for that ?

Not very elegant but works:

lmap a {o p q} {append a _1}
o_1 p_1 q_1

What would be a good command body to set a string in front of each list
element ?

Thank you,
Harald

Rich

unread,
Sep 27, 2018, 3:01:15 PM9/27/18
to
You might not consider it very 'elegant', but this works:

% lmap a {o p q} {set {} 1_$a}
1_o 1_p 1_q

It does create an additional variable, in this case the "empty string"
variable.

jda...@gmail.com

unread,
Sep 27, 2018, 3:29:23 PM9/27/18
to
try:

string cat i_ $s

this works too:

return -level 0 i_$a

but it is kind of weird

Dave

Roderick

unread,
Sep 27, 2018, 3:36:42 PM9/27/18
to


On Thu, 27 Sep 2018, Harald Oehlmann wrote:

> What would be a good command body to set a string in front of each list
> element ?

Perhaps:

lmap a {o p q} {format 1_%s $a}


Roderick

unread,
Sep 27, 2018, 5:07:40 PM9/27/18
to


On Thu, 27 Sep 2018, jda...@gmail.com wrote:

> try:
>
> string cat i_ $s


I see, a new string subcommand. And there are now "Obsolete Subcommands":

string bytelength
string wordend
string wordstart

I think, these comands may be usefull. Any substitute?

Brad Lanam

unread,
Sep 27, 2018, 5:48:47 PM9/27/18
to
On Thursday, September 27, 2018 at 2:07:40 PM UTC-7, Roderick wrote:
> On Thu, 27 Sep 2018, jdavebr wrote:
>
> > try:
> >
> > string cat i_ $s
>
>
> I see, a new string subcommand. And there are now "Obsolete Subcommands":
>
> string bytelength
> string wordend
> string wordstart
>
> I think, these comands may be usefull. Any substitute?

string bytelength is not useful. It returns a length used internally by Tcl
which doesn't have any meaning to the caller.
Really should never have been exposed.

Always use string length.

stefan

unread,
Sep 28, 2018, 3:39:30 AM9/28/18
to
> May I use lmap ? What is the right body command for that ?

Whether it is right or not depends, how will the output be used?

a) as a list: use [lmap]
b) as a string:

set suffix _1
set l {o p q}
string cat [string map [list " " "$suffix "] $l] $suffix

Stefan

Ralf Fassel

unread,
Sep 28, 2018, 4:08:00 AM9/28/18
to
* Rich <ri...@example.invalid>
| % lmap a {o p q} {set {} 1_$a}
| 1_o 1_p 1_q
>
| It does create an additional variable, in this case the "empty string"
| variable.

Since we have the 'a' variable anyway, why not (mis?)use it:

lmap a {o p q} {set a 1_$a}

?

R'

Roderick

unread,
Sep 28, 2018, 6:47:39 AM9/28/18
to


On Thu, 27 Sep 2018, Brad Lanam wrote:

> string bytelength is not useful. It returns a length used internally by Tcl
> which doesn't have any meaning to the caller.
> Really should never have been exposed.

If I take a string from a file that I want to manipulate with tcl,
I realy may need its byte lenth and not its string length.

I continously edit big, very big files or sets of big files with
programs, sometimes C, lex, tcl, or scripts that call ed.

Of course, the byte length is unnecessary if you remain in the
frame of tcl, if all what your program does remain viewed by
tcl.

> Always use string length.

That is not always what I want, but really the byte length.

Should I use it "always", even if that is not what I want and need?

Rodrigo

Rich

unread,
Sep 28, 2018, 8:47:07 AM9/28/18
to
Roderick <hru...@gmail.com> wrote:
>
>
> On Thu, 27 Sep 2018, Brad Lanam wrote:
>
>> string bytelength is not useful. It returns a length used internally by Tcl
>> which doesn't have any meaning to the caller.
>> Really should never have been exposed.
>
> If I take a string from a file that I want to manipulate with tcl,
> I realy may need its byte lenth and not its string length.

Option 1: read the string in binary mode for the input channel, then
the bytelength exactly equals the string length.

Option 2: (for encoded data) use the appropriate 'encoding' incantation
to convert to an output string before output to the file, which gives a
binary string, where bytelength equals string length, then output to
the file with the file set to binary mode.

> I continously edit big, very big files or sets of big files with
> programs, sometimes C, lex, tcl, or scripts that call ed.
>
> Of course, the byte length is unnecessary if you remain in the
> frame of tcl, if all what your program does remain viewed by
> tcl.

The bytelength command does not give you 'bytelength' (the name is,
unfortunately, misleading). It gives you "storage in bytes" used by tcl
*in the frame of tcl*. You can not use 'bytelength' for the purposes
you indicate above, it will not give you correct results.

>> Always use string length.
>
> That is not always what I want, but really the byte length.

No, what you 'want' is to adjust the 'encoding' on your input/output
channels so that you read what you want and/or output what you want.
And if you do have a need to know "length in bytes in output file" then
you need to use binary mode on your channels and the 'encoding' command
to encode in order to obtain binary data from non-binary Tcl strings in
order to measure the length in bytes of an output item in a file.

> Should I use it "always", even if that is not what I want and need?

It (bytelength) is never going to do what you appear to think it does.

Rich

unread,
Sep 28, 2018, 8:47:46 AM9/28/18
to
Hmm... Yeah, that does work as well. Didn't think of that angle.

Ralf Fassel

unread,
Sep 28, 2018, 10:33:23 AM9/28/18
to
* Rich <ri...@example.invalid>
| > If I take a string from a file that I want to manipulate with tcl,
| > I realy may need its byte lenth and not its string length.
>
| Option 1: read the string in binary mode for the input channel, then
| the bytelength exactly equals the string length.
>
| Option 2: (for encoded data) use the appropriate 'encoding' incantation
| to convert to an output string before output to the file, which gives a
| binary string, where bytelength equals string length, then output to
| the file with the file set to binary mode.

Example:

# write an Unicode character to a file
% set text \u306F

% string length $text
1
% set fd [open tmp.txt w]
file7
% fconfigure $fd -encoding utf-8
% puts -nonewline $fd \u306F
% close $fd

# lets see what is in there:
% exec od -t x1 tmp.txt
0000000 e3 81 af
# three bytes...


# get the bytes instead of the char:
# use binary encoding
% set fd [open tmp.txt r]
file7
% fconfigure $fd -encoding binary
% set txt_binary [read $fd]
ã ¯
% string length $txt_binary
3


# now read it again, with correct encoding:
% set fd [open tmp.txt r]
file8
% fconfigure $fd -encoding utf-8
% set txt_utf_8 [read $fd]

% string length $txt_utf_8
1


HTH
R'

Roderick

unread,
Sep 28, 2018, 11:12:21 AM9/28/18
to

Thanks Rich & Ralf, I saved this answer for the future!

Rodrigo.

On Fri, 28 Sep 2018, Ralf Fassel wrote:

> Example:
>
> # write an Unicode character to a file
> % set text \u306F
> は
> % string length $text
> 1
> % set fd [open tmp.txt w]
> file7
> % fconfigure $fd -encoding utf-8
> % puts -nonewline $fd \u306F
> % close $fd
>
> # lets see what is in there:
> % exec od -t x1 tmp.txt
> 0000000 e3 81 af
> # three bytes...
>
>
> # get the bytes instead of the char:
> # use binary encoding
> % set fd [open tmp.txt r]
> file7
> % fconfigure $fd -encoding binary
> % set txt_binary [read $fd]
> ã?¯

Rich

unread,
Sep 28, 2018, 1:34:46 PM9/28/18
to
Roderick <hru...@gmail.com> wrote:
> [-- text/plain, encoding quoted-printable, charset: UTF-8, 50 lines --]
>
> Thanks Rich & Ralf, I saved this answer for the future!

The good news is that, provided you tell Tcl what you want it to do,
that handling different character encodings becomes almost trivial.

And once you do things properly (setting encodings on channels
correctly or using the 'encoding' command when needed) everything just
works, and you have zero need for the 'bytelength' string subcommand.

Also, bytelength will give you incorrect information in at least one
case (incorrect in that it will be a value you do not expect and is not
useful).

Tcl strings can contain an ASCII null character (unlike C strings).

If they do contain an ASCII null, then 'string bytelength' != 'file
bytelength'.

$ rlwrap tclsh
% set null "\0"

% string length $null
1
% string bytelength $null
2
% set fd [open /tmp/test-null {WRONLY CREAT TRUNC}]
file5
% puts -nonewline $fd $null
% close $fd
% file size /tmp/test-null
1
%

0 new messages