Ace128 has asked for the wisdom of the Perl Monks concerning the following question:


Ok, I have been thinking about this on and off for a while now, but having trouble starting with the code as Im not sure how others may wanna use it. And the main problem is the structure to create to make it easy to traverse through it all.. The idea is to create something that is easy to expand, and as much errorprone as possible. It feels to me that I should use some kind of "state machine" or something. So, I turn torwards you bright monks here, for feedback and suggestions.

So, I'm doing my own version of a shell, and beeing creative as I am, I wanna implement the following:

Say a user types:

>> search
and press enter. Now it may display something like:

>> <cursor is here>
Mode: search

Showing that we are now in "search mode" where a number of additional funktions may be available. Since this shell is a module, one is supposed to register a callback with a function. Now, say we continue by typing:

>> file perlmonks*
and we use the shell for searching. This may then show:

>> <cursor is here>
Mode: search
Query: SELECT database.file FROM database WHERE database.file LIKE("perlmonks%");

where the query output is for now just debuginfo showing up, but that is what is created in the background later.

If we now continue with:
>> size > 50mb <enter is pressed>
we get:

>> <cursor is here>
Mode: search
Query: SELECT database.file, database.size FROM database WHERE database.file LIKE("perlmonks%") AND database.size > 50000000;

Seems pretty nice eh? Now, to expand this functionality abit, I also want the following to be possible. Notice we have "file" above. Then we are now also able to do:
>> file <and press enter>
We get:
Mode: search -> file
and the query is still the same. However if we type:

>> *wisdom NOT *stupid*
we get:
Mode: search -> file
Query: SELECT database.file, database.size FROM database WHERE database.file LIKE("perlmonks%") AND database.file LIKE("%wisdom") AND NOT database.file LIKE("%stupid%") AND database.size > 50000000;

So, building the query up dynamicly as we type! If we press ESCAPE, we go up one level like:

>> <ESC>
Mode: search
but the query hasn't changed.

So, we have "functions" and "keywords" (or whatever name is suitable). Functions are those that we can "enter" by just typing them and pressing enter. Or, by typing them and then keywords afterwards. If we enter the function, we have now access to the keywords directly.

I now turn to you and ask the big question. What structure is the best to implement to make this reality?

So far I've come up with the following hash structure (which is what users of the shell module pass in to the shell module):
::Core:: 'search' => { '-command' => 'search', '-autocomplete' => ['file', 'full_path', 'just_dir', 'extensio +n'], '-information' => "Search the database.", '-command_function' => \&searchDatabase, '-mode_function' => \ +&searchMode, }, 'search::file' => { '-command' => 'file', '-autocomplete' => ['file', 'full_path', 'just_dir', 'extensio +n'], '-information' => "Search the database.", '-command_function' => \&searchDatabase, '-mode_function' => \ +&searchMode, }, 'search::show' => { '-command' => 'show', '-autocomplete' => { '-pattern' => '/modtime|modification\stime/modtime +/', # like a s/// '-namespace' => 'search::*', '-exact' => ['file', 'full_path', 'just_dir', 'ext +ension'], } '-information' => "Search the database.", '-command_function' => \&searchDatabase, '-mode_function' => \ +&searchMode, }, ::mp3Plugin:: 'search' => { '-command' => 'search', '-autocomplete' => ['artist', 'title'], '-information' => "Search the mp3 music.", }, 'search::artist' => { '-command' => 'artist', '-autocomplete' => [], '-information' => "Search the artist.", '-command_function' => \&searchDatabase, '-mode_function' => \ +&searchMode, },
I love using hashes like this since this makes it easy to add more functionality without breaking things too much. The hashkeys are "namespaces". Meaning that when you say "search::file", "file" is a child to "search".

With the "mp3Plugin" we have a small problem though. The first namespace (search) collide with the one in the core. I guess the best way to solve that is to ignore it if it's already created...

Otherwise, I guess this is rather OK way to define everything in a readable fashion. The problem now is to create a nice structure out of this that isnt too complicated. I was thinking some kind of tree, and then I recalled the lovely CPAN... and then I became little confused as I'm not sure what could be the most suitable to use for this!

What say you?
/ Ace

This idea is patented and copyrighted and all that legal stuff! ;)

Replies are listed 'Best First'.
Re: Different "states" in a my own Shell
by geekphilosopher (Friar) on Feb 23, 2007 at 17:54 UTC

    Copyrighted and patented, eh? Just so you know, if you haven't ACTUALLY patented it yet, I don't think you will be able patent it in the future, since you've just published it :)

    I don't know anything on CPAN that specifically applies to your scenario, but you might want to look at the programs Katapult (for KDE) and Quicksilver (for OS X). They're not shell replacements, but they do the handy search-plugin thing really well (especially Quicksilver). Browsing over the code for Katapult (which is open source) may give you some ideas.

      Nah, I was mostly kidding although it's an idea I haven't seen ANYONE do yet and that could be quite nifty... And as some say, you can't really patent an idea... too bad as I am full of those... :)

      And yea, know about those thanks. Quicksilver is an app with GUI. I still use the terminal.. and can easly add GUI too it if wanted. You know, as a Linux user I know the power of the terminal ;)
Re: Different "states" in a my own Shell
by zentara (Archbishop) on Feb 23, 2007 at 17:06 UTC
    The idea is to create something that is easy to expand, and as much errorprone as possible. ....... This idea is patented and copyrighted and all that legal stuff!

    I think Microsoft already has the patent on "as errorprone as possible". :-)

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
Re: Different "states" in a my own Shell
by chanio (Priest) on Feb 23, 2007 at 19:15 UTC
    CPAN has a lot of free-to-use modules that might help you getting most of your idea done.

    I question if the agressive commerce has something to do with creativity. One of CPAN's main purpose is to act as a staircase for creators: someone publishes something that was created after a lot of investigation and skills. Everybody expects that some other might use it to achieve something even bigger. The benefit is shared by all the community.

    Please, apreciate that most of the real present creation is coming from opensource and free & uncompromised improvements. If I were planning to become rich before putting my code into existence, I wouldn't expect to reach there very soon. But I could hope that exposing my ideas they might reach someone that is able to convert them in a real thing.

    Besides, I would use a structured config file to keep all my posibly growing list of functions and commands. XML or YAML would do. YAML is also, easy to edit.

    This chaotic and conservative state of property might have started by a guy who after being rejected by his girlfriend went to an office and patented the Moon and other Solar System satelites as his property. He has never reached those lands, but everybody has to buy him a piece of it if they are planning to go some day.

    This is the most silly thing because it is based on the presumption that everybody respects the actual state of patents. (remember USA's law of property in the 1800 when the British Encyclopedia was not theirs in America).

    So, keep on coding, and don't wait until you become rich to create something original.

Re: Different "states" in a my own Shell
by Joost (Canon) on Feb 23, 2007 at 21:44 UTC
    This idea is patented and copyrighted and all that legal stuff! ;)
    Just to make sure: you can't copyright ideas in general - and AFAIK in software you can only copyright implementations (of an idea). I'm also under the impression that you can't patent ideas, only specific classes/kinds of constructs - though software patent law is too messy right now to be certain of anything. Just to be safe I didn't read anything else in your post. :-)

      Well, nowadays I really think it's better to be first (specially since all this law stuff just confuses me, and besides, I prefer beeing on the opensource side, since things get more and faster evolved there), and become known by beeing first instead of trying to patent everything restricting others to use the idea by having to pay. Money may come later as a nice aftereffect instead. :) Atleast I hope so...
Re: Different "states" in a my own Shell
by andyford (Curate) on Feb 23, 2007 at 22:11 UTC

    I think you should use bash functions and aliases and dynamically alter the $PS variables to get your screen to show your last commands.

    You can even make things turn colors for some kind of syntax highlighting.

    non-Perl: Andy Ford