AutoHotkey Community

It is currently May 26th, 2012, 10:49 pm

All times are UTC [ DST ]




Post new topic This topic is locked, you cannot edit posts or make further replies.  [ 1036 posts ]  Go to page Previous  1 ... 15, 16, 17, 18, 19, 20, 21 ... 70  Next
Author Message
 Post subject:
PostPosted: October 28th, 2009, 5:10 pm 
Offline

Joined: July 14th, 2006, 12:31 am
Posts: 290
Location: Berlin
hello lexikos, coult you tell me something about the topic http://www.autohotkey.com/forum/viewtop ... 886#305886 and the following entries?


Last edited by ladiko on November 2nd, 2009, 9:08 am, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: October 28th, 2009, 5:43 pm 
Offline

Joined: March 27th, 2008, 2:14 pm
Posts: 700
Lexikos: I like the idea of changing the parsing loop to allow parsing an object.

More specifically, I would like to see the "InputVar" param be changed to a generic expression. It would not break any current implementations of Loop, Parse since expressions handle variables the same way InputVar does:
Loop, Parse wrote:
The name of the variable whose contents will be analyzed. Do not enclose the name in percent signs unless you want the contents of the variable to be used as the name.
But it would simultaneously add the possibility of parsing the contents of an object, plus allow things like this:
Code:
Loop, Parse, "\.*?+([{}])^$|"
    StringReplace, regExLiteral, regExLiteral, %A_LoopField%, \%A_LoopField%, All

(Just an example. Yes, I know that in reality escaping literal text for use in a regex pattern is much faster with RegExReplace)
Edit: Here's an example that's more clear:
Code:
Loop, Parse, "value1|value2|value3", |
    MsgBox % A_LoopField

_________________
Scripts - License


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 1st, 2009, 5:03 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
While testing a recent change (the first item on my "summary"), I noticed an undocumented feature I had forgotten about: If an object is automatically created by multi-param mode (e.g. obj[x,y] := z where obj[x] didn't exist), the new object receives the base of the parent object.

This can be useful when the base object defines generic array-like behaviour, since the newly created object will automatically support all of the functions of the parent object. However, it can also be undesired, and even if it were documented would probably still be obscure. Additionally, the behaviour can be replicated by using a __Set meta-function:
Code:
x := Object("base", Object("__Set", "x_Setter"))

x[1,2,3] := "v"
; Above effectively does this:
;   x_Setter(x, 1, 2, 3)        ; Creates object for x[1].
;   x_Setter(x[1], 2, 3, "v")   ; Creates object for x[1][2].
;   x[1][2][3] := "v"

; Check value was assigned correctly and base objects of sub-objects were set:
MsgBox % x[1,2,3] . "`n" . (x[1].base == x.base) . " " . (x[1,2].base == x.base)

x_Setter(x, p1, p2, p3)
{   ; Since p3 is a required param, below cannot directly recurse:
    x[p1] := Object("base", x.base)
    ; However, if there are still parameters to be processed and
    ; the above sets "base" to an object where .__Set=="x_Setter",
    ; our caller may invoke us again for x[p1], x[p1][p2], etc.
}
It relies on the the function's minimum parameter count being enforced and the following documented behaviour: "If a meta-function does not return any value (not even a blank value), the operation continues as normal."

The current behaviour can be controlled by setting base to something other than x.base, or not setting it at all. As for the next revision, there are two options:
  1. Keep the behaviour, but document it and how to disable it.
  2. Remove the behaviour, but document how to replicate it.
I'm leaning toward the second option, which is probably safer. Any thoughts?
Sean wrote:
Currently x.y(z) := v is a meaningless/incorrect expression, so, how about giving it a meaning?
Thanks for the suggestion, I'll consider implementing it.
wiseley wrote:
I would highly appreciate you could implement a loop parsing of an expression
infogulch wrote:
I like the idea of changing the parsing loop to allow parsing an object.
I'll consider ways to support expressions generically in InputVar parameters. It might also tie in with another change I had hoped to make: allowing commands to use results of expressions (i.e. pure integer/float results for numeric params and possibly objects/arrays for some commands). However, I think that it might require significant/low-level changes (or an ugly hack), so I won't be implementing it soon.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 2nd, 2009, 4:01 am 
Offline
User avatar

Joined: May 24th, 2009, 5:35 am
Posts: 2099
Location: Iowa, USA
I've been working with Pseudo-Properties (which is an absolutely fantastic concept for AHK-IMO), something along the lines of:
Code:
"".base.__Get  := "String_Properties"
String_Properties(string, key) {
   Return, key="length"?StrLen(string):(key is integer?SubStr(string, key, 1):)
}
var := "AutoHotkey"
MsgBox, % "Length: " var.length "`n5th Character: " var[5]

Currently is there any way to use this concept similar to how a function can be called from an external file as long as it's in the Lib folder (and the file name is the function name)? If not, are there any plans to create functionality for something like a Default Base Standard Library file?

_________________
Image
Recommended: AutoHotkey_L
Basic Webpage Controls


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 2nd, 2009, 9:02 am 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Lexikos wrote:
The current behaviour can be controlled by setting base to something other than x.base, or not setting it at all. As for the next revision, there are two options:
  1. Keep the behaviour, but document it and how to disable it.
  2. Remove the behaviour, but document how to replicate it.
I'm leaning toward the second option, which is probably safer. Any thoughts?


I would like to have the second option :)

_________________
AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 2nd, 2009, 10:17 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
jethrow, I would use something like this:
Code:
; YourScript.ahk
String_Lib()
var := "AutoHotkey"
MsgBox, % "Length: " var.length "`n5th Character: " var[5]

; String.ahk
String_Lib() {
    "".base.__Get := "String_Properties"
}
String_Properties(string, key) {
    return key="length" ? StrLen(string) : (key+0!="" ? SubStr(string, key, 1) : "")
}
i.e. Call a library function to include the appropriate file and initialize the pseudo-properties. Also note: is, in and contains aren't supported in expressions, and by definition, the ternary operator (a?b:c) requires three operands. If you omit the third operand (a?b:), it becomes "the binary operator". :P (It may cause the overall expression to fail if the winning branch was omitted or it isn't the last operation in the expression.) Incidentally, I have a tentative plan to improve syntax validation to prevent these sorts of errors.
Quote:
If not, are there any plans to create functionality for something like a Default Base Standard Library file?
I suppose you mean a file that would be loaded automatically into every script; I have no plan to implement that.

I've thought about implementing an "/i file" or "/include file" switch, which could serve the same purpose (i.e. after editing the .ahk association in the registry) but also has other uses.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 3rd, 2009, 12:24 am 
Offline
User avatar

Joined: May 24th, 2009, 5:35 am
Posts: 2099
Location: Iowa, USA
Lexikos wrote:
Also note: is, in and contains aren't supported in expressions ...
Actually, I didn't think that syntax should work - but since it did, I didn't worry about it :). Thank you for clarifying.

Lexikos wrote:
Incidentally, I have a tentative plan to improve syntax validation to prevent these sorts of errors.
Sounds like a great idea to me.

Lexikos wrote:
I've thought about implementing an "/i file" or "/include file" switch ...
Thanks for the information. I don't know much about editing the registry, but I'm sure I'll learn if you implement this feature :D

_________________
Image
Recommended: AutoHotkey_L
Basic Webpage Controls


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 3rd, 2009, 1:00 am 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
Lexikos wrote:
Incidentally, I have a tentative plan to improve syntax validation to prevent these sorts of errors.
Although I don't have a rationale against the check, I'm afraid that it'll break numerous scripts of mine, definitely almost all of my custom libraries, which is currently 37, let alone plain scripts. I used x?:z a lot more than x?y: whose behavior is rather restrictive against current syntactic error check of AHK. Personally I took it as a handy syntactic sugar, looking far more elegant than If ... Then .... And I suppose some other languages/compilers also support this as I think I saw a few times codes written like that, IIRC.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 3rd, 2009, 9:24 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
Omitting the winning branch of the ternary op causes a sort of "stack underflow"; i.e. because the winning branch contains no operands, no value is pushed onto the stack. If there are too few tokens on the stack when an operator is being evaluated, evaluation of the overall expression is aborted. I suppose the only way around it (to make it "legal") would be to treat the omitted branch as if an empty string was specified. The purist in me thought this a bad idea, instead preferring that a future version specifically point out the syntax error and require that the user correct it. On the other hand, it could be exclusively allowed where the result of the ternary op will be discarded; e.g. x ? y(), z ? x:=z.
Quote:
I used x?:z a lot more than x?y:
That reminds me, I had considered letting x?:z be equivalent to x?x:z as an alternative to simply copying C#'s ?? operator or changing the existing behaviour to match Lua's or operator.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 3rd, 2009, 1:12 pm 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
Lexikos wrote:
evaluation of the overall expression is aborted.
I was aware of that, however, that does not always hold true.
Code:
x:=1
y:=1?:2, z:=3
MsgBox % z
x:=1, y:=1?:2, z:=3
MsgBox % z

Quote:
I suppose the only way around it (to make it "legal") would be to treat the omitted branch as if an empty string was specified.
Maybe you misunderstood me. I didn't suggest to make it legal. I'm well aware of that it'll produce a runtime error when it succeeds, but, I don't care about the error when I use x?:z. So my request was that don't pop-up an error message at compile time as is currently, just leave it to the user, or at least give some option to turn it off.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 3rd, 2009, 10:46 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
Sean wrote:
I was aware of that, however, that does not always hold true.
I was very careful to word it accurately; I did not say it will happen every time you omit part of a ternary op, I said it happens "If there are too few tokens on the stack when an operator is being evaluated". Since the result of the first comma-delimited statement becomes the result of the overall expression, it must remain on the stack while the other statements are evaluated. Stack underflow does not occur because the second assignment has two operands: 'x' (the result of x:=1) and 'y'. Because 'x' is below 'y' on the stack, the actual assignment that occurs is x:=y.

This sort of "hidden consequence" is why I want to either make it legal or prevent it entirely.
Quote:
Maybe you misunderstood me. I didn't suggest to make it legal.
No. I suggested an alternative.
Quote:
So my request was that don't pop-up an error message at compile time as is currently, just leave it to the user, or at least give some option to turn it off.
Obviously it won't produce an error message if it's "legal".


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 3rd, 2009, 11:02 pm 
Online

Joined: October 13th, 2009, 10:09 pm
Posts: 1389
Some bugs with this test code:

Code:
if("test")
   msgbox
msgbox, % "tset". "test"
msgbox, % ("test"). ("test")


On V35
Code:
Error: Call to nonexistent function.

Specifically: if("test")

   Line#
--->   001: if("test") 
   002: MsgBox
   003: MsgBox,"tset". "test"
   004: MsgBox,("test"). ("test")
   004: Exit

The program will exit.


On V33:
Code:
Error: Unsupported use of "."

Specifically: . "test"

   Line#
   001: if ("test") 
   002: MsgBox
--->   003: MsgBox,"tset". "test"
   004: MsgBox,("test"). ("test")
   004: Exit

The program will exit.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 4th, 2009, 1:01 am 
Offline

Joined: February 12th, 2007, 7:54 am
Posts: 2462
Lexikos wrote:
Because 'x' is below 'y' on the stack, the actual assignment that occurs is x:=y.
I knew it still had a bad consequence (noted for later argument).
Quote:
Obviously it won't produce an error message if it's "legal".
That'll be perfectly fine with me as I'm only concerned about the error message pop-up. IMO, this is a hard-to-make unintentionally kind of error, otherwise, there would have been already a post in the Bug section as the consequence would appear a mysterious bug. Or the user was aware of that it's not legitimate but it's looking too awesome/concise to abandon. So, my point was: why putting an effort into what nobody was dissatisfied with.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 4th, 2009, 5:44 am 
Offline
User avatar

Joined: May 24th, 2009, 5:35 am
Posts: 2099
Location: Iowa, USA
fragman wrote:
Some bugs with this test code:
Code:
if("test")
Lexikos wrote:
Quote:
Revision 34 - October 24, 2009
  • Changed: Command names must be terminated with a space, tab or comma.
The same "bug" occurs with:
Code:
while("test") ; simple solution: while ("test")

_________________
Image
Recommended: AutoHotkey_L
Basic Webpage Controls


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 4th, 2009, 7:21 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
fragman & jethrow: thanks, I'd forgotten about those two.
Sean wrote:
IMO, this is a hard-to-make unintentionally kind of error,
I think the issue is more that it is hard to debug when it does happen.
Sean wrote:
So, my point was: why putting an effort into what nobody was dissatisfied with.
Nobody, eh? That's me.


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic This topic is locked, you cannot edit posts or make further replies.  [ 1036 posts ]  Go to page Previous  1 ... 15, 16, 17, 18, 19, 20, 21 ... 70  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 2 guests


You can post new topics in this forum
You can 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:
Powered by phpBB® Forum Software © phpBB Group