It is currently Wed, 25.Nov 2009 - 06:08

All times are UTC + 1 hour [ DST ]




Post new topic Reply to topic  [ 1 post ] 
Author Message
 Post subject: SWITCH - What's to be told about it.
PostPosted: Sun, 30.Aug 2009 - 03:15 
Offline
mostly harmless
mostly harmless
User avatar

Joined: Mon, 07.Aug 2006 - 14:04
Posts: 19
Location: /earth/europe/it
Introduction
This guide is meant to explain how the switch(5) command works.
There isn't very much to say about it, but a couple of examples
should be enough to figure out the potential of this command.



Requirements
As usual, I'd like to stress the important role of the help files,
as it often is a more than good starting point.

Synopsis:
switch (<control text>) { (<switch>) { <body> } }

    <control text> is the string which will be switched to check against
    <switch> is a possible value that <control text> could assume
    <body> is the action which follows if ( <control text> == <switch> )

As for the description, the only interesting parts about it IMO are when it
mentions that everything is assumed to be a string and that spaces are ignored.



Getting started
At the time I met xelo and joined this site I used to hook a different
404 numeric for almost every custom command I scripted (e.g.: !movies).

At the end, a script of mine looked like something similar to this:
Code:
on -404 0 "% % !movies" { /* some actions */ }
on -404 1 "% % !tunes"  { /* some actions */ }
on -404 2 "% % !games"  { /* some actions */ }

and so on.. :biggrin:

The real problem I had was to find a way to put everything inside a single 404 piece of code.
I first thought that I could set up something like this, with a little help from if(5):
Code:
on -404 "% % !%" {
    @ command = after(! $2)  /* isolates the command's name from the ! symbol */
    if ( command == [movies] ) { /* some actions */ }
    if ( command == [tunes]  ) { /* some actions */ }
    if ( command == [games]  ) { /* some actions */ }
}


At this point, the problem IS solved, but I wasn't quite satisfied with the result.
It felt too much like re-writing the same stuff over and over again.
Luckily for me, xelo had the answer :D Did you ever take a look at his games?
You didn't? Well, it's about time you examine them, because they provide a clear
explanation of what switch is and how it works!



Scripting
The best way to code the whole thing turns out to be:
Code:
on -404 "% % !%" {
    @ command = after(! $2)
    switch ($command) {
        (movies) { /* some actions */ }
        (tunes)  { /* some actions */ }
        (games)  { /* some actions */ }
        (*)      { /* unknown command triggered */ }
    }
}


As you can see, the code is more organized, nice and essential.



Concrete examples
Now I'll try to provide some interesting examples showing the switch power.

A simple switch that checks the value of an arbitrary input:
Code:
alias test {
    switch ( $0 ) {
        ( foo ) {
            /* do action for "foo" */
        }
        ( bar ) ( blah ) {
            /* do action for "bar" or "blah" */
        }
        ( * ) {
            /* <do action for everything else> */
        }
    }
}

:?: There is something new in the previous alias.

:arrow: First of all, the abundant use of the space before and after the words bar and blah,
and the one between the parenthesis: TekNap ignores these spaces, according to the help files.

:arrow: Then, the "( bar ) ( blah ) {" part.
You could test the alias' behaviour for yourself by inputing /test bar and /test blah
from the command line, or, if you're just too lazy to do that, I can guarantee you
that they will have the exact same effect.
Why is this? Because that multiple switch is evaluated as if the code was:
Code:
if ( [$0] == [bar] || [$0] == [blah] ) { /* do action for "bar" or "blah" */ }


Note: I haven't tested up to how many multiple switches are allowed, but I think I succesfully
(yet desperately!) covered for all the uppercase/lowercase letters of the alphabet once, when
I didn't know about string-testing functions like isalpha(6), isdigit(6), isalnum(6), ...

:arrow: Finally, the "( * ) {" AKA default case. It's good practice among programmers to include it in the code and it could also be useful as a debugging tool.


Now that we're more familiar with the basic structure let's complicate our life a little bit.
Say we want to script a command which requires taking care of several jobs using a certain
amount of command line options.

The ad hoc command will be: !movies and it will work in a public channel.
Its purpose might be to store information about movies users liked, like imdb does.

Its synopsis:
    !movies -add <title> <genre> <director> <year of production>
    !movies -h or !movies -help
    !movies -list or !movies -show
    !movies -search <title> or !movies -find <title>
    !movies -sort <bytitle|bygenre|bydirector|byyear>

Here is the code which should take care of all that:
Code:
on -404 "% % !*" {
    /* $0  is the channel (first %),
       $1  is the user who triggers the command (second %),
       $2  is !% (one word only - the command's name, plus the ! sign)
       $2- is !* (there could be spaces and further words)
       $3- is ANY other option that a command _could_ have
    */
    switch ($2-) {
        (!tunes) { /* we could also have other commands, remember? */ }
        (!games) { /* custom actions for the games command */ }
        (!movies*)(!film*) {
            switch ($3-) { /* checks if any other options are given */
                (-add) {
                    say What should we add? You didn't enter any field.
                    say The correct syntax is: \"$2 -add <title> <genre> <director> <year of production>\"
                }
                (-sort) {
                    say You forgot to specify the parameter by which the list will be sorted
                    say The options are: \"$2 -sort bytitle|bygenre|bydirector|byyear\"
                }
                (-search)(-find) {
                    say Search for what?
                    say The correct syntax is: \"$2 $3 <title>\"
                }
                (-list)(-show) { /* code which displays all the movies in the database */ }
                (-add % % % %) { /* code which adds the new movie entry */ }
                (-help)(-h) { /* code which prints some help to the user */ }
                (-sort %) { /* code which presumably sorts the list and prints it */ }
                (-search %)(-find %) { /* code which searches for the given string ($4) */ }
                (-*) {
                    say Unknown option \"$after(- $3-)\". Please, use '$2 -h' if you don't know what you're doing.
                }
                (*) {
                    say Unavailable feature.. Maybe it'll be on the next release \;P
                }
            }
        }
    }
}

As you can see, switches can also be nested to help you sort levels of parameters and arguments.



Hints

Error:
    TekNap: Unknown command: SWITCH($VARIABLE)
Remedy:
    Place a space between the word 'switch' and the '(' symbol in your script.
(Yes, it took me a looong while before realizing it :oops:, so don't make the same mistake! :P)


Error:
    Throughout this guide I have used the /* comments */ soon after the switched value,
    but this could cause some malfunctions when you load a script, like:
      - seeing your comment appearing in the input line);
      - Expression syntax SWITCH: case body not found where expected.
Remedy:
    If you need to place a comment do it on a different line than the one in which the
    '{' symbol appears (preferably the one after that).

It might seem a little bit frustrating at first, having all these parenthesis and tabulations,
your scripts might turn huge, so I suggest you use an appropriate text editor which has a
neat feature named Code Folding, which will help you a lot on your work!



I think that's all for this (yearly :holy:) guide.
Tek on! and of course, Q'apla'! :thumb:

_________________
Perhaps today is a good day to learn TekNap (and die!) :D


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC + 1 hour [ DST ]


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
© 2008 phpbbstylists.com
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group