Friday, 3 July 2009

The Twouble with Tcl

From time to time I do a bit of tcl. Mostly as maintenance for existing tcl programs. I haven't made up my mind entirely about it yet - I've seen some very powerful programs in tcl, and yet occasionally I'm still "surprised" by a feature.

I spent a couple of hours today trying to figure out why a tcl program of mine wasn't running, and so I've made some notes:

Real languages don't have reserved words


In tcl, you can redifine parts of the language in tcl itself. For example if you wanted to redefine if, just write a new function:
proc if {cond expres} {
puts "cond is $cond"
puts "expr is $expres"
}

set a 1
if {$a == 1} {
puts hello
}
Sounds neat. In fact proc itself is just a command that takes 3 arguements (name, arguements, and body). However, don't start using simple names in your tcl languages like this:
proc open {} {
set ::alarm_socket [open_socket $::options(-alarm_host)]

foreach host $::options(-hosts) {
verbose "open $host"
set ::sockets($host) [open_socket $host]
# set up an event handler for when data is readable on this socket:
fileevent $::sockets($host) readable [list process $host]
# initialise socket timeout with open time
set ::socket_t($host) [clock seconds]
}
}
Because open is what you might call a reserved word. (I should have known with open, but should I really have to remember all the reserved words?)

The error looked something like this:
$ ./test.tcl
invalid command name "::tcl::tm::UnknownHandler"
while executing
"::tcl::tm::UnknownHandler ::tclPkgUnknown msgcat 1.4"
("package unknown" script)
invoked from within
"package require msgcat 1.4"
("uplevel" body line 2)
invoked from within
"uplevel \#0 {
package require msgcat 1.4
if { $::tcl_platform(platform) eq {windows} } {
if { [catch { package require registry 1.1 }] } {
..."
(file "/usr/lib/tcl8.5/clock.tcl" line 23)
invoked from within
"source -encoding utf-8 [file join $TclLibDir clock.tcl]"
(procedure "::tcl::clock::format" line 3)
invoked from within
"clock format [clock seconds]"
(procedure "alarm_timeouts" line 3)
invoked from within
... and so on. Yeuch! And it was encountered with this one line:
   puts "$::argv0: [clock format [clock seconds]]"
The problem? I redefined open, which was used internally by clock.

Real languages don't have types:


You can do lots of nice things in tcl without types, in a similar (but different) way to perl.
set a world
puts "Hello $a" ;# prints 'Hello world'
set a 1
incr $a
puts "$a + 2" ;# prints '2 + 2'
This looks normal to someone used to perl and tcl. Noticed how I don't need format specifiers or concat functions. You can also do this:

set a pu
set b ts
$a$b "Hello World"

Which prints:
Hello World

Real languages don't have comments


They have a comment command of course! And the comment command is a command that takes arguments (the comment itself) that aren't evaluated. Except that because of this, you can't have an unmatched brace in a comment:
# if ($sometest) {
$somecode
#}

The tcl solution?
if (0)
blocks or the like...

Conclusion


So if you haven't yet learnt tcl, I encourage you to find a tcl hackers tcl program, and delve into it to see just how it works.

If you try to learn tcl only by writing it and not by reading others' code, then you'll learn tcl with the habits you're used to, and you will possibly miss some of the powerful features.

After all, C programmers can program C in just about any language!

Monday, 1 June 2009

Evolution 2.26 - scrolling performance improves (finally!)

I recently upgraded to Gnome 2.26, and not noticing too many new features I just discovered this: Evolution 2.26.2 finally handles scrolling large mail folders effectively.

I have in excess of 1000 emails in some of my mail folders, and I have a Logitech MX400 Laser mouse which lets you disengage the "clutch" (the wheel that typically clicks in defined steps as you scroll it) so that you can do large freewheeling scrolls with one finger movement. This helps to navigate large documents, web pages, and folder lists.

Previously in Evolution, scrolling the wheel by a large amount meant that when the wheel stopped, Evolution would keep scrolling for some time as it tried to keep up with all the events.

Now, however, the folder stops scrolling as soon as my mouse wheel stops moving. Good stuff!

(For the record, Claws has had the nicer behaviour for some time, just in case you were thinking of telling me it was a new mouse driver!)

Thursday, 21 May 2009

Another Password Generator

So I wrote a password generator, why not?!

I had some free time recently, I was about to reset someone's password for a site I administer, and I thought it would be nice to have a small script generate semi easy to remember but semi secure passwords.

Firstly, I usually use either of these two one liners:
$ for ((n=0;n<10;n++)); if="/dev/urandom" count="1"> /dev/null | uuencode -m -| head -n 2 | tail -n 1 | cut -c-8; done

$ for ((n=0;n<10;n++)); if="/dev/urandom" count="1" bs="8">/dev/null | uuencode -m - | tail -n 2 | head -n 1 | cut -c -8; done


The results are similar. You get a bunch of passwords looking like this:
zZqTqB23
Fh0qKx05
skhDDXPN
GmToF0H0
yWieCLfu
6lmrPOm5
Tq+Tz/G/
ybYWDvXp
u018CGWA
9FyV1zJq

Which is handy for setting up lots of accounts, which I do occasionally. However, people hate them because 9FyV1zJq is harder to remember than their cat's name.

The script I just wrote (in Perl) uses word lists and random numbers to generate passwords like this:
kagu757elf
matt37spif
hiss378gyro
err410eyed
zest957pirn
twin452road
czar210mum
mors720cops
floc684wok
odor384hymn


Sure, these aren't as secure, but they're better than "tiggles".

Oh, and my wordlists come from wordlist.sourceforge.net

#!/usr/bin/perl -w

# A utility to create reasonable strength and semi-easy to remember passwords
# out of word lists and random characters.
#
# Copyright 2009 Iain Buchanan. Freely redistributable and modifiable.

use strict;

my @lists = ('/home/iain/personal/ispell-enwl-3.1.20/altamer.0',
'/home/iain/personal/ispell-enwl-3.1.20/altamer.1',
'/home/iain/personal/ispell-enwl-3.1.20/altamer.2',
'/home/iain/personal/ispell-enwl-3.1.20/american.0',
'/home/iain/personal/ispell-enwl-3.1.20/american.1',
'/home/iain/personal/ispell-enwl-3.1.20/american.2',
'/home/iain/personal/ispell-enwl-3.1.20/british.0',
'/home/iain/personal/ispell-enwl-3.1.20/british.1',
'/home/iain/personal/ispell-enwl-3.1.20/british.2',
'/home/iain/personal/ispell-enwl-3.1.20/english.0',
'/home/iain/personal/ispell-enwl-3.1.20/english.1',
'/home/iain/personal/ispell-enwl-3.1.20/english.2',
'/home/iain/personal/ispell-enwl-3.1.20/english.3');

my @wordlist;

foreach my $list (@lists) {
open (WL, "$list") or print "Couldn't open wordlist '$list': '$!', skipping.\n";

while () {
chomp;

next if (length >= 5); # ignore long words
next if /^[A-Z]/; # ignore Nouns & abbvs.

push @wordlist, $_;
}
close (WL);
}

for (1..10) {
print $wordlist[int (rand ($#wordlist))];
print int (rand (999));
print $wordlist[int (rand ($#wordlist))];
print "\n";
}

Tuesday, 12 May 2009

The results are in: It's Apathy by a landslide!

Thanks to everyone who took part in my recent poll "What would you like me to post more about?" That is, all 6 of you, including myself. The results are as follows:


























































Votes%Post
3(50%)IT related technical articles
3 (50%)
Linux howto's, tips & tricks
3 (50%)Renewable energy power station bio's
2 (33%)Reviews of my electronics (phone, set top box, espresso machine, etc)
2 (33%)Random thoughts & musings on anything
1 (16%)Personal & Family events
0 (0%)Dell Precision M6300 howto's for running Linux
0 (0%)I can't stand reading anything you write!



There were 6 unique voters, including myself. The poll ran for most of April, 2009. Voters could select multiple entries.

Conclusions

So what? Well, there were nowhere near enough votes for me to make any drastic changes. Most of my visits are for the ever-popular Vmware keyboard page. I can safely say that the results can be completely ignored!

If you don't agree, comment!