if 0 {[Richard Suchenwirth] 2004-12-05 - Here's a slight rewrite of [SS]' minimal [IRC] client (see that page) - adding * indentation * user names in bold * other messages in italic * own posts are marked in blue as a rudimentary color scheme [WikiDbImage irc.gif] Still, it was only 38 LOC, last time I looked :) } package require Tk set ::server irc.freenode.org set ::chan #tcl set ::me $tcl_platform(user) text .t -height 30 -wrap word -font {Arial 9} .t tag config bold -font [linsert [.t cget -font] end bold] .t tag config italic -font [linsert [.t cget -font] end italic] .t tag config blue -foreground blue entry .cmd pack .cmd -side bottom -fill x pack .t -fill both -expand 1 bind .cmd post proc recv {} { gets $::fd line # handle PING messages from server if {[lindex [split $line] 0] eq "PING"} { send "PONG [info hostname] [lindex [split $line] 1]" return } if {[regexp {:([^!]*)![^ ].* +PRIVMSG ([^ :]+) +:(.*)} $line -> \ nick target msg]} { set tag "" if [regexp {\001ACTION(.+)\001} $msg -> msg] {set tag italic} if [in {azbridge ijchain} $nick] {regexp {<([^>]+)>(.+)} $msg -> nick msg} .t insert end $nick\t bold $msg\n $tag } else {.t insert end $line\n italic} .t yview end } proc in {list element} {expr {[lsearch -exact $list $element]>=0}} proc post {} { set msg [.cmd get] if [regexp {^/me (.+)} $msg -> action] {set msg "\001ACTION $action\001"} foreach line [split $msg \n] {send "PRIVMSG $::chan :$line"} .cmd delete 0 end set tag "" if [regexp {\001ACTION(.+)\001} $msg -> msg] {set tag italic} .t insert end $::me\t {bold blue} $msg\n [list blue $tag] .t yview end } proc send str {puts $::fd $str; flush $::fd} set ::fd [socket $::server 6667] send "NICK $::me" send "USER $::me 0 * :PicoIRC user" send "JOIN $::chan" fileevent $::fd readable recv bind . {exec wish $argv0 &; exit} ---- ''[escargo] 8 Mar 2006'' - If ''lines of code'' is really an important metric to you, the three [set] commands could be replaced with the [foreach] [idiom] to do multiple assignments: if 0 { foreach {::server ::chan ::me} {irc.freenode.org #tcl $tcl_platform(user)} break } That would cut the number of lines by two. - [RS]: Well, yes, but no... and you'd need a [list] anyway, since you refer to [tcl_platform]... My major metrics is not lines of code, but of course I try to remove all redundancies - [KISS]. But I do prefer scripts with <72 lines, just because in printout they fit on a single page :-) I also noticed the expressions in the [if] commands were unbraced. Is that right? Is that good style? - [RS]: I have the rule for myself that an [if] condition that consists of a single function call (typically returning 0 or 1) can be unbraced - I consider the time needed to parse the strings "0" resp. "1" small enough that I rather spare myself the visual clutter of {[[...]]}. Matter of taste, of course. ---- vote on reddit at [http://programming.reddit.com/info?id=2ugx] - that forum promped a rewrite of the above in [Ruby] at http://whytheluckystiff.net/ruby/smircer.rb ---- Could someone provide this code with verbose comments for those of us that are just learning? There are a few things about this code that I dont understand. For one, I dont see how this snippet deals with IRC's ping/pong behaviour (is it hardcoded into the socket command?). But thats not at all the extent of the confusion, hence the request for verbosity. - [RS]: Your [wish] is my command :^) See [PicoIRC 0.2 explained]. Forgive this post if it breaks the wiki's ettiquite, its my first. ---- [picoIRC 0.3] is a more elaborate version by [SS]. ---- [MJ] - added handling of the PING request. Perhaps its just me, but that ping handler is sending some nastyness into the running of the script syntax error in expression "[lindex [split $line] 0] eq "PING"" ("if" test expression) while compiling "if {[lindex [split $line] 0] eq "PING"} { send "PONG [info hostname] [lindex [split $line] 1]" return }" (compiling body of proc "recv", line 4) invoked from within "recv" [RS]: I suppose it's the "eq" operator. You seem to be running an old Tcl from before 8.4 (which came out 2002...) - just replace ''eq'' with == for a quick fix. ---- [Category Application] - [Category Internet]