DOCUMENTATION FOR RUBY4MIRC (FOR INSTALLATION SEE README.TXT) ======================================================================= Last update on October 20th 2007 for version 1.1 0. FAQ > What is "supported mode"? 1. RUNNING RUBY CODE > Method 1: Invoking the parser > Method 2: Embedding Ruby into your script files > Caching embedded code 2. COMMUNICATING WITH MIRC > Sending commands to mIRC: mirc("command") -> nil > Calling mIRC identifiers: mirc.identifier -> Object > Accessing and setting mIRC variables: mirc[:varname] = value > Passing variables from mIRC to Ruby > Special global variables > $RUBYDLL_VERSION > $MIRC_VERSION_SUPPORTED 3. MIRC SIGNAL CALLBACKS AND OUTPUT HANDLING > RUBY_LOADED > RUBY_ERROR > RUBY_STDOUT_BEGIN / RUBY_STDERR_BEGIN > RUBY_STDOUT / RUBY_STDERR > RUBY_STDOUT_END / RUBY_STDERR_END 4. EXAMPLES > One-Liners > Embedded Ruby ======================================================================= 0. FAQ > What is "supported mode"? Ruby4mIRC relies on the CLB (Common Language Bridge) which is part of the Dynamic Languages 4 mIRC project. The CLB extends the way a DLL can communicate with mIRC, enabling it specifically to be able to access event specific identifiers, like $opnick in the ON OP event. In addition to extended functionality, this mode is roughly 3 times faster than using the standard SendMessage API documented in the mIRC help (/help SendMessage). However, a drawback of this mode is that it requires specific knowledge about the makeup of the mIRC binary that is being run. In other words, to make use of the CLB's extended functionality, the version of mIRC used with the DLL must be explicitly supported by the CLB, hence "supported mode". CLB is able to fallback on the standard SendMessage API when the version of mIRC is not supported, but beware that you may be using a script that requires the extended functionality that the CLB provides. If you are using Ruby4mIRC in unsupported mode, verify that you do not have any embedded scripts inside events that make use of event specific identifiers. In such a case, your events will not function properly. 1. RUNNING RUBY CODE You can run Ruby code in one of two ways using Ruby4mIRC. > Method 1: Invoking the parser The first way to run Ruby code is to simply invoke the evaluation method by simply calling: /rb RUBY_CODE_HERE * Note that /rb is a convenience alias specified in ruby.mrc You can also use $rb(RUBY_CODE_HERE) to retrieve the return value from a block of ruby code. There is also a /rb.async command which runs Ruby code asynchronously, though *this feature is experimental* and is known to crash. /rb.async can take a callback alias when passed in the form: /rb.async --CALLBACK RUBY_CODE_HERE alias CALLBACK { do_something } Using this method, you can also `require` or `load` your own Ruby scripts and have them run alongside mIRC. This can be used to load important classes or modules that you will later use with the second method. > Method 2: Embedding Ruby into your script files Most people don't just want Ruby sitting on the sidelines while mIRC does its thing. For this reason, you have the ability to embed your Ruby code directly into your mIRC scripts seamlessly. To do this, you must "memorize" the following snippet of code to have Ruby4mIRC jump from mIRC code into your Ruby script: if $($has_ruby,2) { # Ruby code goes here } If you're curious to know what it does, I can explain. $has_ruby will return a call to the DLL to invoke the interpreter and parse the code starting at the beginning of the if extending to the end. The command must be $() evaluated to get $scriptline so that it knows where to begin parsing from. The identifier then returns $false so that mIRC ignores the if-block, happily skipping over the otherwise- invalid script. > Caching embdedded code You may now be thinking that parsing the file for each call may be expensive, and you would be right. For this reason, you are given a similar function `$has_cached_ruby` which is used in the exact same manner as the above function. The only difference is that the parser will cache the results of your code for the next call, which will save many CPU-cycles per call. Caching is not "on" by default because most people will most likely have to make changes to their code before finalizing it, and having Ruby4mIRC cache all the time would cause a lot of headaches in debugging. For this reason, the recommended flow of coding is to use $has_ruby until you are positive that you have a working product, and only then change the starting line to $has_cached_ruby. It may also be beneficial to add a note to yourself that you are caching the script results. 2. COMMUNICATING WITH MIRC The `mirc` object / method is the only noun you should need to know to communicate from Ruby to mIRC. Depending on how it's called, it can perform many different actions. > Sending commands to mIRC: mirc("command") -> nil You can use Ruby to communicate with mIRC using the `mirc` global method. The syntax is mirc("command"). A simple example would be: mirc "echo -a hello world" A '/' prefix is allowed but not required when sending commands. The result of this method is always nil. > Calling mIRC identifiers: mirc.identifier(...) -> Object If the mirc method is called with no arguments, it will return an object that can be used to call mIRC identifiers and return values from mIRC to Ruby. Note if Ruby4mIRC is running in supported mode (see section 0. FAQ for details on "supported mode") then you will have access to event specific identifiers when using embedded Ruby inside events. An example of this is listed at the end of this document. A simple example usage would be: mirc.me # Returns your current nickname mirc.calc("1 + 2") # Returns 3 Parameters can be passed in as regular Ruby objects and will be converted to their String representation when passed to mIRC. The return values from mIRC will also automatically be converted back into proper Ruby objects as shown in the calc example returning the Fixnum value 3 and not the String "3". Floating point values as well as numbers of arbitrary bases will also be converted if possible: mirc.calc("1 / 2").inspect # => 0.5 mirc.lower("0xA").inspect # => 10 mirc.lower("0xA NOT!").inspect # => "0xa not!" Similarly, the Ruby objects `true`, `false` and `nil` will also be converted to their mIRC equivalents: $true, $false, $null. This includes converting from mIRC to Ruby. Note that you cannot use this syntax to return properties. The following code will not do what you'd expect: mirc.sockname(:somename).status This will call the `status` method on what is likely to be a String result. To get around this, you can use mIRC's $eval identifier to evaluate your call manually: mirc.eval("$sockname(somename).status") IMPORTANT: Ruby4mIRC cannot access the values $1, $2, ..., or $1-, $2-, ..., etc. This is a technical limitation of the DLL API implemented in mIRC. For ON TEXT events, you can use $rawmsg instead, otherwise you will have to pass the value into a *global* variable. See the "Passing variables" section for details. > Accessing and setting mIRC variables: mirc[:varname] = value mIRC variables can be accessed and set from Ruby either by using the mirc("set %var value") method or by using the [] accessor method to get and set values, for example: mirc[:myvar] = "Hello world" # Sets %myvar to Hello world mirc["myvar"] # Returns "Hello World" The arguments are all properly converted to Strings, so Symbols are a valid way to access a variable name, as shown above. The '%' prefix is not required but allowed. mirc["%myvar"] will also return "Hello world". Note that just like for identifiers, the Ruby objects will automatically be converted to the proper mIRC equivalent value. So the code: mirc[:myvar] = nil Will set %myvar to $null, even though it returns nil to Ruby. The same holds true for `true` and `false`. IMPORTANT: The CLB currently does not support local variables. Attempting to return the value of a local variable using this method will result in a nil value. > Passing variables from mIRC to Ruby It is likely that you will need to pass data to and from Ruby when creating a script. While the CLB does support event specific identifiers to reduce the number of data needed to be manually passed in and out of mIRC, the CLB does not support local variables or the $1- identifier family, and therefore cannot communicate completely transparently with mIRC. To solve this problem, you must unfortunately set the variables that Ruby4mIRC needs to read globally, unsetting them at the end of your alias or event. /set -u0 will not work to avoid the unset command at the end. A way to access local variables via the CLB is being worked on. An example of communicating between mIRC and Ruby would be: alias ruby.reverse { set %data $1- rb mirc[:data] = mirc[:data].reverse echo -a %data unset %data } /ruby.reverse Hello world > Special global variables > $RUBYDLL_VERSION Returns the version of the Ruby4mIRC DLL. > $MIRC_VERSION_SUPPORTED -> true/false This will return true if you are running a version of mIRC that is compatible with this DLL. See "supported mode" in the FAQ for more information. 3. MIRC SIGNAL CALLBACKS AND OUTPUT HANDLING Ruby4mIRC sends a few signals to mIRC now and then that can be caught by the scripter. For more information on the SIGNAL event, read mIRC's help under "ON SIGNAL". The following signals are supplied: > RUBY_ERROR This signal will be triggered in the rare case where the CLB cannot communicate with mIRC. This is a critical error and should be handled by halting further script processing. Error details will be filled into $1-. > RUBY_LOADED Triggered when Ruby is finished loading into memory. You can use this to load any important Ruby support libraries. The identifier $1 will be filled with the "supported mode" value as $true / $false (whether or not the CLB is running in supported mode). See "supported mode" in the FAQ for more information on this value. > RUBY_STDOUT_BEGIN / RUBY_STDERR_BEGIN Triggered when Ruby is about to read a block of text either from standard output or standard error. You can use this to /linesep if you wish. > RUBY_STDOUT / RUBY_STDERR Triggered when Ruby reads *one line* of data from standard output or standard error. $1- is filled with the line contents. > RUBY_STDOUT_END / RUBY_STDERR_END Triggered when Ruby finishes printing a block of text from standard output or standard error. 4. EXAMPLES See ruby.mrc for example code.