mIRC Home    About    Download    Register    News    Help

Print Thread
#225190 27/08/10 09:58 PM
Joined: Aug 2010
Posts: 4
P
Self-satisified door
OP Offline
Self-satisified door
P
Joined: Aug 2010
Posts: 4
Hi everybody

I'm trying to eval a block of code. Specifically I want to store many lines of code in a var to eval them later, like:

Code:
%cmd = echo -a first line
%cmd = %cmd $+ echo -a second line
%cmd = %cmd $+ echo -a last line
...
$eval(%cmd)

... maybe even separating the lines with | or $crlf or something else, but I've gotten no success yet frown

Any ideas?

Last edited by PedroFialho; 27/08/10 09:59 PM.
Joined: Aug 2010
Posts: 5
N
Nutrimatic drinks dispenser
Offline
Nutrimatic drinks dispenser
N
Joined: Aug 2010
Posts: 5
Use $chr(124) instead of | when setting a variable.
This should do the trick:

Code:
alias test1 {
  set %cmd echo -a first line
  set %cmd %cmd $chr(124) echo -a second line
  set %cmd %cmd $chr(124) echo -a last line
  test2 %cmd
}
alias test2 {
  tokenize 124 $1-
  var %tmp = 0
  while (%tmp < $0) {
    inc -u0 %tmp
    $eval($ $+ %tmp,2)
  }
}


Joined: Aug 2010
Posts: 4
P
Self-satisified door
OP Offline
Self-satisified door
P
Joined: Aug 2010
Posts: 4
I was doing just that, only it was the whole string :]
Like:
Code:
var %cmd = echo -a first line
%cmd = %cmd $chr(124) echo -a second line
%cmd = %cmd $chr(124) echo -a last line

$eval(%cmd)

That evaluates the whole thing as a single line command, thus treating everything after the first echo as plain text.

$eval'ing each command really does the trick, except for when a if or while appears =/. I think $eval is not meant to process command blocks, or maybe it wasn't ever thought through; there's nothing at all about it on the help file, and I haven't found anything similar on the web. In fact, the documentation says it "(...) allows you to recursively evaluate identifiers and variables in a line of text.", so I'm starting to think code batchs isn't $eval stuff.

As an alternative, I thought about declaring aliases on the fly, which btw I never imagined to be possible, but it is - the downside: only single-line aliases.

The particular work I'm willing to use it in is an OO interface for mIRCScript, so I'm thinking of using that on declaring methods. Right now I'm using external aliases, but I want to make it possible to declare it inside the class definition.

These are the only methods I could think of for storing blocks of code to execute them later.

I wouldn't say it is a design flaw on $eval, as surprisingly I've seen no request or anything on that matter, maybe it was never needed. That was the first thing I tried because I'm also a PHP developer and I thought it would be similar to PHP eval hehe, which interprets a string as normal source code.

But if anyone knows some other way, that would be great help.

Thanks for the help, by the way.

UPDATE: Actually, I just tested, if you "serialize" a block of code into a line and do
Code:
$eval(alias someName %code)

and later call the alias, it does the trick; that works well as far as I've tried, but it will add the alias to the default alias file, i.e. aliases.ini
As a workaround, you may remove the alias later by adding it empty (/alias my_alias), but it's kinda ugly to fill the user aliases file with lots of strange aliases.
Maybe creating a file only for those aliases, or even creating the alias, running it and removing it right away (crazy), I'll see what happens and then I tell the story.

If anybody has a better idea than all this stuff let me know lol

Last edited by PedroFialho; 28/08/10 01:10 AM.
Joined: Feb 2006
Posts: 546
J
Fjord artisan
Offline
Fjord artisan
J
Joined: Feb 2006
Posts: 546
as you've observed, $eval() only lets you evaluate a piece of text a certain number of times, it has no regard for command separators inside that text :P

special constructs such as if/while and even local variables declared with /var are interpreted before the routines that evaluate $eval() even come into play, which is why the following doesn't behave as intended:

Code:
  var %cmd = if (1) echo success
  $eval(%cmd, 2)


what you want can be done quite simply using functions of mIRC that are able to perform a series of commands (almost) as though they were simply inserted into your scripts editor. the multi-server related commands /scon and /scid will execute the given text as a line of code within the context of the current routine (that is to say, local variable declared within the scope in which the command is performed are accessible). unfortunately, $1- is not carried over which is rather regrettable :P

some examples:

Code:
  var -s %cmd = if (1) echo success
  scid $cid %cmd


Code:
  var -s %cmd = var $(%cmd2 = another variable |,) echo $(%cmd2,)
  scid $cid %cmd


Code:
  var -s %cmd = var $(%var2 = 1 |,) while (%var2 <= 5) $({ echo -a %var2 |,) inc $(%var2 },)
  scid $cid %cmd


$( ,) is simply short for $eval( ,0). as you can see, as long as you construct the line of code properly (preventing and delaying evaluations wherever necessary), you can create even the most complex series of commands. /timer also has a command parameter and thus can also be used in an equivalent manner to run lines of code. however, timers trigger commands in their own scope (as though a separate alias was called) which may or may not be more appropriate for you.

there's definitely a lot to say on the subject of mIRC's interpreter, if you have any other questions or run into any problems do let us know!


"The only excuse for making a useless script is that one admires it intensely" - Oscar Wilde

Link Copied to Clipboard