Writing good scripts

From Eggdrop Wiki

Jump to: navigation, search

Contents


This is a list of things to keep in mind for writing good, well-behaved Eggdrop scripts.

DOs

Include a license

This is perhaps the single most important point in this article. If you don't license your work properly, it will be very difficult for others to carry on your work if you quit. If you don't understand licensing or don't want to bother researching which license you should use, the author recommends using the ISC license. It's a very permissive license, basically telling people that they can do whatever they want with your code. One thing to note here however is to not attempt to write your own license. If you don't like the ISC license, another good license to use is always GPL version 2, which is the license used by Eggdrop itself. Note that GPL version 3 is NOT compatible with GPL version 2, and if used would make it impossible to bundle your script with Eggdrop.

Use UDEFs boldly

Use a user-defined channel flag type for making it possible to turn on or off your script on a per-channel basis, unless the script doesn't interact with channels. Use: .chaninfo #channel to view current 'User defined channel flags'. In the below example, use: .chanset #channel +hello to turn the script On. Use: .chanset #channel -hello to turn it Off.

setudef flag hello
proc myHello {nick uhost hand chan arg} {
	if {![channel get $chan hello]} { return }
	puthelp "PRIVMSG $chan :Hello, $nick!"
}


Syntax-check your code

Syntax-check your code using the online #Tcl pastebin or nagelfar or even the Tcl syntax checker plugin for Komodo Edit. Note that the #Tcl pastebin is designed for checking Eggdrop scripts and will check for problems with Eggdrop-specific commands. The other two are designed for Tcl in general and won't check Eggdrop-specific commands without some modification.

Put everything inside a namespace

Name it the same as the script. Don't infinitely nest namespaces ie ::my::very::own::and::awesome::namespace. Don't overuse [namespace current]. Declare procs with their full path.

package require Tcl and eggdrop

Use package require to specify which versions of Tcl and Eggdrop are required to run the script.

package require Tcl 8.5
package require eggdrop 1.6.20


Use Packages

Tcllib is the de facto standard Tcl library, most people will have this installed, and if they don't, should probably go and install it. It comes with a vast array of different useful libraries. Instead of writing your own variant of SHA1, FTP, JSON parser etc, use the one in Tcllib. If you're working with some kind of standard, such as the ones mentioned, chances are that Tcllib has a library for it. Some particularly useful packages from an Eggdrop perspective are htmlparse, particularly the ::htmlparse::mapEscapes function, and ip, for manipulating IP addresses.

Other useful and often-installed packages, that are not part of Tcllib, include the TLS OpenSSL extension, often used for https, and Trf, often used for gzip compression.

Indent your code properly

One tab = one level of indentation. Get with the new millennium and upgrade your editor if you think tabs are annoying.

DON'Ts

Confuse Lists with Strings

Two different worlds

Use the wrong output queue

quick != fast

Return incorrectly

Write this

Pollute the global namespace

No code outside namespace/procs

Use expr in if statements

It's already an expression

Example

# runts.tcl --
#
#	This script will hand out runts to people in specified channels.
#
# Copyright (c) Year(s), Company or Person's Name <E-mail address>
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# v1.0 by Person's Name <E-mail address>, Month DD, YYYY
 
package require Tcl 8.5
package require eggdrop 1.6.20
 
namespace eval ::runts {
	setudef flag runts
	if {![info exists runtsGiven]} { variable runtsGiven 0 }
}
 
proc ::runts::pubRunt {nick uhost hand chan arg} {
	variable runtsGiven
	if {![channel get $chan runts]} { return }
	putserv "PRIVMSG $chan :Here, $nick, have a runt. This is my [incr runtsGiven] runt given."
	return 1
}
 
namespace eval ::runts {
	bind pub - !runt ::runts::pubRunt
	putlog "Loaded runts.tcl v1.0 by Person's IRC Nickname"
}
Personal tools