if 0 {Richard Suchenwirth 2004-12-05 - Here's a slight rewrite of SS' minimal IRC client (see that page) - adding
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 <Return> 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 . <Escape> {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 [L1 ] - 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.