mIRC Home    About    Download    Register    News    Help

Print Thread
Page 1 of 2 1 2
#223941 03/08/10 02:12 PM
Joined: Apr 2010
Posts: 969
F
Hoopy frood
OP Offline
Hoopy frood
F
Joined: Apr 2010
Posts: 969
I know it's undocumented, but there is a small bug with it, none the less:
Code:
tokenize 32 this is a test
var %test = $* %test
var %test2 = %test2 $* 
echo -a %test
echo -a %test2
the variables only get filled with the last token.
From the example it echos:

"this"
"test"


I am SReject
My Stuff
Joined: Nov 2006
Posts: 1,559
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Nov 2006
Posts: 1,559
There had been several reports about the behaviour of $* in constructs like that. If I remember correctly, Khaled stated that he'd rather not fiddle with this identifier any more, as "fixing" this or that quirk will likely break scripts that rely on the very quirk (and/or will produce other quirks). In other words, he had to make a decision, and decided on continuity over consistency... Keep in mind that $* is around for a *very* long time; superseded by the consistent, more versatile and first of all: documented goto- and while constructs. laugh

(Q: Maybe I'm plain dopey... how do I search the forums for "$*"? )

Horstl #224062 05/08/10 01:47 AM
Joined: Jan 2009
Posts: 116
Vogon poet
Offline
Vogon poet
Joined: Jan 2009
Posts: 116
Isn't $* an undocumented feature to begin with? What does it even do? *why* isn't it in the manual? :_)


http://zowb.net

/server -m irc.p2p-network.net -j #zomgwtfbbq
(ssl on port 6697 and 7000)
Knoeki #224069 05/08/10 02:44 AM
Joined: Nov 2006
Posts: 1,559
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Nov 2006
Posts: 1,559
For a general explanation of $* and undocumented stuff in general, have a look here

Knoeki #224085 05/08/10 07:40 AM
Joined: Dec 2002
Posts: 5,411
Hoopy frood
Offline
Hoopy frood
Joined: Dec 2002
Posts: 5,411
The $* identifier was added long before support for goto and while loops was added. It was subsequently removed from the help file although I kept it in mIRC for backwards compatibility.

Khaled #224087 05/08/10 07:47 AM
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
It *is* a pretty useful identifier. I know many scripters who still use it for new scripts. Things like:

//tokenize 32 nick1 nick2 nick3 | msg $* hi

Are much more elegant than the equivalent while loop. Perhaps resurrecting it would be something to consider?


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
argv0 #224089 05/08/10 08:36 AM
Joined: Dec 2002
Posts: 5,411
Hoopy frood
Offline
Hoopy frood
Joined: Dec 2002
Posts: 5,411
The $* identifier is too much of a kludge - the way it works makes it difficult to improve or extend it without side-effects. So while I could add it back to the help file, I would still not be able to make changes to it.

Joined: Dec 2002
Posts: 5,411
Hoopy frood
Offline
Hoopy frood
Joined: Dec 2002
Posts: 5,411
Just to clarify: the $* identifier allows you to iterate a command over a number of parameters. It does this by evaluating the whole command line once and then executing that for each parameter. However, in your script, you want the entire command line to be re-evaluated at every execution. While it might be possible to implement such a change, it would change the way $* works and all existing scripts that use $* would behave differently.

Khaled #224103 05/08/10 12:39 PM
Joined: Feb 2006
Posts: 546
J
Fjord artisan
Offline
Fjord artisan
J
Joined: Feb 2006
Posts: 546
if this proposed change is implemented as though $* were substituted by a literal '$1' then '$2' then '$3' etc. and then the entire line evaluated as normal, i don't see it being all that problematic. the alternative being to keep using an arbitrary string as a placeholder and perform substitutions before evaluating the line, resulting in double evaluations with $* used inside identifiers.

based on what i've seen, there are very few scripts that would be affected by such a change, ie. made slower by unnecessary re-evaluations of the rest of the line, and fewer still that would break (relying upon the evaluating once approach when using such things as $rand() or custom identifiers that shouldn't re-evaluate).

$* is very commonly used by scripters in either extremely simple commands, usually not involving any other identifiers (and when it does they're usually not complex in nature) or the popular work around for the OP's issue involving /scon or /scid. but in the latter form the scripter generally tries to delay evaluation of code in the line anyway, allowing it to evaluate with /scon or /scid's command. this change would only serve to make things easier for them.

i strongly believe the proposed change would only be perceived as an addition to the language rather than a modification :P


"The only excuse for making a useless script is that one admires it intensely" - Oscar Wilde
jaytea #224127 05/08/10 04:25 PM
Joined: Apr 2010
Posts: 969
F
Hoopy frood
OP Offline
Hoopy frood
F
Joined: Apr 2010
Posts: 969
I am FroggieDaFrog, and I support this message


I am SReject
My Stuff
jaytea #224145 05/08/10 06:54 PM
Joined: Dec 2002
Posts: 344
D
Pan-dimensional mouse
Offline
Pan-dimensional mouse
D
Joined: Dec 2002
Posts: 344
The point is that making such a modification to $* doesn't add any functionality that doesn't already exist and would break at least some scripts that already are using it. That is really all that matters, so this change won't (shouldn't) happen.

drum #224147 05/08/10 07:07 PM
Joined: Sep 2005
Posts: 2,881
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Sep 2005
Posts: 2,881
I think that sometimes backwards compatibility needs to take a back seat so that the application can evolve.

Any issues that arise out of changing $* will be minor ones that anybody could get help with in 5 minutes by posting on a scripting forum..

mIRC has just ditched codepage support in favour of UTF8. In my opinion it's about time for mIRC to evolve and not worry so much about backwards compatibility. If your script stops working and you don't want to fix it, you still have the choice of using any of the 6.xx versions or 7.1 smile

hixxy #224152 05/08/10 07:43 PM
Joined: Oct 2004
Posts: 8,330
Hoopy frood
Offline
Hoopy frood
Joined: Oct 2004
Posts: 8,330
Normally, I agree with you hixxy, and I actually do agree with what you said except in this context. shocked

Unless adding extra support for $* is actually beneficial in some way other than using fewer characters to accomplish the same thing, I don't see any reason to break any scripts to do so. Now, if adding additional functionality to it will improve scripts in some notable way, then I'd agree that we should move forward with it. From what I know of $*, using a normal loop performs the same function just as well and if not as efficiently, at least close enough not to matter unless you're looping a LOT of times.

Personally, I just don't use it even if it's "easier" to type that than to type a loop. I'd rather not have to update a script because an undocumented feature was changed or removed when I can perform the same thing without many more characters and no noticeable performance loss. Also, I think it's much easier to browse through someone's script to help them troubleshoot it when you're seeing a WHILE loop (or even GOTO, though in almost all cases, that's not the best method) than to watch for $*. That's just my opinion, though.


Invision Support
#Invision on irc.irchighway.net
Joined: Sep 2005
Posts: 2,881
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Sep 2005
Posts: 2,881
Whilst while loops can be used to accomplish the same thing as $* (albeit using a much longer method), while loops aren't the topic being discussed here.

Here is why I think $* should be changed:

Take this script for example,

Code:
//tokenize 32 ~1 $!time ~3 | echo -a $*


Output:

~1
$time
~3

Now let's say that you want to manipulate each of those strings using $mid:

Code:
//tokenize 32 ~1 $!time ~3 | echo -a $mid($*,2)


This doesn't work and I think it should. At the moment you have to introduce some kludgy workaround which can introduce unexpected results for scripters who are unaware of the side effects of commands that evaluate parameters twice. Consider this:

Code:
//tokenize 32 ~1 $!time ~3 | scid -r echo -a $!mid( $* ,2)


Output:

~1
21:01 (or whatever the current time is)
~3

This is clearly evaluating $!time twice, which is where the undesired behaviour comes in from workarounds like this. It also looks messy and hard to follow.

The real danger would come when somebody uses a script like this:

Code:
on ^*:text:*:#:{
  echo # $+(<,$nick,>)
  scid -r echo # $+(~, $* ,~)
  haltdef
}


..which would of course evaluate anything that was said on the channel.

hixxy #224163 05/08/10 10:14 PM
Joined: Dec 2002
Posts: 344
D
Pan-dimensional mouse
Offline
Pan-dimensional mouse
D
Joined: Dec 2002
Posts: 344
The loop version of your example would be:

Code:
//tokenize 32 ~1 $!time ~3 | var %i = 1 | while (%i <= $0) { echo -a $mid( [ $+($,%i) ] ,2) | inc %i }


Yes, it's somewhat longer code, but it's simple and easy to understand. I wouldn't call this "a much longer method". I'd call it "a slightly longer method that is much clearer and provides much more flexibility". Since $* is not supported anymore, and since while loops are simple, there's really no reason to use $* at all.

As for accidental double evaluation, I agree that double evaluation is a problem and should be addressed. I've already created a feature suggestion thread on that topic.

What it comes down to is that for every case you can come up with where changing the behavior of $* would solve a problem, someone else can come up with a reverse case where the old behavior is necessary for $* to solve a problem. The only thing you'd be doing is shifting the way $* works to suit your personal needs.

drum #224166 05/08/10 10:30 PM
Joined: Sep 2005
Posts: 2,881
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Sep 2005
Posts: 2,881
$* also has speed benefits over a while loop. I've written a benchmark script (posted on a pastebin so it doesn't stretch this thread!)

My tests show that $* is approximately 3 times faster. Probably because there's less code to interpret.

$* has clear benefits over a while loop; it's shorter (and thus more convenient) and faster.

hixxy #224170 06/08/10 12:50 AM
Joined: Dec 2002
Posts: 344
D
Pan-dimensional mouse
Offline
Pan-dimensional mouse
D
Joined: Dec 2002
Posts: 344
Originally Posted By: hixxy
My tests show that $* is approximately 3 times faster. Probably because there's less code to interpret.


Actually it looks like it's at least a couple orders of magnitude faster. Your script isn't showing it properly because the resolution of $ticks (at least on my system) is somewhere around 15-16 ms.

For example, try this code: http://pastebin.com/6tNKWjpR (It takes about 7 seconds to do the loop test on my system, so don't be alarmed if it takes some time to finish.)

My results for this code:

Quote:
$*: 31 ms.
Loop: 6661 ms.


This actually makes a lot of sense. It appears that the speed issue isn't with the while loop, but instead the problem is the need to use either $gettok or string concatenation to reference the i-th token, which is very slow (relatively speaking).

Also note that by replacing

Code:
noop $calc( [ $+($,%i) ] *3)


with

Code:
noop $calc( $($+($,%i),2) *3)


the code is actually even slower, around 9-10 seconds on my system. It seems that $() is noticeably less efficient than using brackets.

Ultimately though it comes down to the issue that modifying $* would break some old scripts. Although there's nothing preventing Khaled from adding a new identifier that does the same thing as $* but works in the way you are asking for.

Khaled #224177 06/08/10 05:48 AM
Joined: Oct 2003
Posts: 3,918
A
Hoopy frood
Offline
Hoopy frood
A
Joined: Oct 2003
Posts: 3,918
I'd support adding it to the help file while not making any changes to its core behaviour or introducing any new functionality. Of course a few tweaks here and there would be nice. Again, I think you'd be surprised to find out how common $* is, despite it being undocumented and old.


- argv[0] on EFnet #mIRC
- "Life is a pointer to an integer without a cast"
drum #224185 06/08/10 07:08 AM
Joined: Sep 2005
Posts: 2,881
H
Hoopy frood
Offline
Hoopy frood
H
Joined: Sep 2005
Posts: 2,881
Your test is actually flawed. $* can only be used once in the current scope, after that it actually doesn't do anything.

Code:
//tokenize 32 1 2 3 | var %i = 10 | while (%i) { echo -a %i | echo -a $* | dec %i }


As you can see, $* works the first time and every subsequent time the echo -a $* is ignored completely whilst the rest of the code in the loop continues to work as expected.

That's why $* is so much faster in your script, because no actual calculations are being performed after the first one.

$* is definitely much faster than the loop alternative though smile

hixxy #224219 06/08/10 04:13 PM
Joined: Dec 2002
Posts: 344
D
Pan-dimensional mouse
Offline
Pan-dimensional mouse
D
Joined: Dec 2002
Posts: 344
Originally Posted By: hixxy
Your test is actually flawed. $* can only be used once in the current scope, after that it actually doesn't do anything.


Thanks. That seems like another good reason to avoid using $* to me... wink

After adjusting for this by using this script, in which I also added a "control" test where only the calculation is removed so we can see how much overhead there is, I get:

Quote:
$*: 4524 ms.
Loop: 7457 ms.
Control: 702 ms.


So, $* is faster, but it's less than a factor of 2 difference.

Page 1 of 2 1 2

Link Copied to Clipboard