 |
AutoHotkey Community Let's help each other out
|
AutoHotkey_L: Arrays, Debugger, x64, COM, #If expression ...
Goto page Previous 1, 2, 3 ... 44, 45, 46 ... 68, 69, 70 Next
|
| View previous topic :: View next topic |
| Author |
Message |
majkinetor ! Guest
|
Posted: Fri Jul 16, 2010 2:10 pm Post subject: |
|
|
| Lexikos wrote: | | or allowing either syntax to be used are possibilities |
I support this idea completely.
About expression efficiency, I think that is not that important. AHK is fast enough now for 99.9% possible usses and rapid development is more important for general purpose script language. In that manner, new syntax possibilities (syntax sugars etc) and features should be more important. |
|
| Back to top |
|
 |
HotKeyIt
Joined: 18 Jun 2008 Posts: 4653 Location: AHK Forum
|
Posted: Mon Jul 19, 2010 8:21 pm Post subject: |
|
|
Hi Lexikos,
can you have a look at this, looks like numbers are not handled properly?
| Code: | 0:=Object(),o:=Object()
0.a:=1,o.a:=1
MsgBox % o.a ;works as expected
MsgBox % 0.a ;does not work but will work if 0:=Object() is in a separate line
MsgBox % o["a"] ;works as expected
MsgBox % 0["a"] ;does not work
MsgBox % o.("a") ;returns empty string (as expected)
MsgBox % 0.("a") ;returns 0.(a) |
Also this displays 1.1 | Code: | 1:=Object()
1.1:=1
MsgBox % 1.1 |
_________________ AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun  |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Mon Jul 19, 2010 9:46 pm Post subject: |
|
|
Numbers are handled just fine, but numbers aren't variables.  |
|
| Back to top |
|
 |
HotKeyIt
Joined: 18 Jun 2008 Posts: 4653 Location: AHK Forum
|
Posted: Mon Jul 19, 2010 10:16 pm Post subject: |
|
|
| Lexikos wrote: | Numbers are handled just fine, but numbers aren't variables.  |
What do you mean  | Code: | 0:="test",123:="another one"
MsgBox %0% ;0 as variable
MsgBox %123% ;123 as variable |
Okay I agree for 1.1 since this is actually a number, but what about this, especially since 0.a works
| Code: | 0:=Object() ;0 as object
0.a:="test"
MsgBox % 0.a ;works if 0:=Object() is in a separate line and not part of expression
MsgBox % 0["a"] ;does not work
MsgBox % 0.("a") ;returns 0.(a) |
_________________ AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun  |
|
| Back to top |
|
 |
infogulch
Joined: 27 Mar 2008 Posts: 649
|
Posted: Mon Jul 19, 2010 10:42 pm Post subject: |
|
|
The VarSetCapacity character fill trick doesn't work anymore:
| Code: | FillChar(char=" ", cnt=100) {
return x, VarSetCapacity(x,64), VarSetCapacity(x,0), VarSetCapacity(x, cnt, Asc(char))
} |
_________________ Scripts - License |
|
| Back to top |
|
 |
HotKeyIt
Joined: 18 Jun 2008 Posts: 4653 Location: AHK Forum
|
Posted: Mon Jul 19, 2010 11:09 pm Post subject: |
|
|
| infogulch wrote: | The VarSetCapacity character fill trick doesn't work anymore:
| Code: | FillChar(char=" ", cnt=100) {
return x, VarSetCapacity(x,64), VarSetCapacity(x,0), VarSetCapacity(x, cnt, Asc(char))
} |
|
It does but not for Unicode version  | Code: | BYTE fill_byte = (BYTE)TokenToInt64(*aParam[2]);
// I assume for Unicode it should be
TBYTE fill_byte = (TBYTE)TokenToInt64(*aParam[2]); |
_________________ AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun  |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Tue Jul 20, 2010 1:19 am Post subject: |
|
|
| HotKeyIt wrote: | What do you mean  |
| Quote: | Such numeric names cannot be used in expressions because they would be seen as numbers rather than variables.
Source: Variables and Expressions |
| Quote: | but will work if 0:=Object() is in a separate line
| I had overlooked this comment. This works only because the var:= part of a standalone assignment is handled separately from the expression part, for performance reasons. It is processed the same way as the variable in 0=a.
| Quote: | 0.a works  | This is a bug. 0 should be interpreted as a numeric literal for use with the default base mechanism, like "".a. Even if it works, it is extremely bad style.
| infogulch wrote: | | The VarSetCapacity character fill trick doesn't work anymore: | VarSetCapacity is designed to fill bytes, not characters, as the RequestedCapacity parameter is in bytes, not characters.
| Quote: | | VarSetCapacity(x,64), VarSetCapacity(x,0) | This trick also won't work as intended in Unicode builds, as the maximum "persistent" allocation is 64 characters (128 bytes), including the null terminator (VarSetCapacity excludes it). |
|
| Back to top |
|
 |
infogulch
Joined: 27 Mar 2008 Posts: 649
|
Posted: Tue Jul 20, 2010 2:38 pm Post subject: |
|
|
| Quote: | | Code: | | VarSetCapacity(x,64), VarSetCapacity(x,0) | This trick also won't work as intended in Unicode builds, as the maximum "persistent" allocation is 64 characters (128 bytes), including the null terminator (VarSetCapacity excludes it). |
Ah I see. Would this be consistent across builds instead? VarSetCapacity(x,64*(A_IsUnicode ? 2 : 1))
| Quote: | | VarSetCapacity is designed to fill bytes, not characters, as the RequestedCapacity parameter is in bytes, not characters. |
Aw damn that's right. Can you think of another method? (well, one that doesn't involve loops ) _________________ Scripts - License |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Tue Jul 20, 2010 10:22 pm Post subject: |
|
|
| infogulch wrote: | | Would this be consistent across builds instead? VarSetCapacity(x,64*(A_IsUnicode ? 2 : 1)) | Yes. You could also just use 128, which would probably be faster as the expression is simpler and the size of allocation makes very little difference.
| Quote: | | Can you think of another method? |
| Code: | FillChar(char=" ", cnt=100) {
if A_IsUnicode
VarSetCapacity(buf, cnt*2, 1)
, DllCall("msvcrt\_wcsset", "str", buf, "int", Asc(char), "Cdecl")
else
VarSetCapacity(buf, cnt, 1)
, DllCall("msvcrt\_strset", "str", buf, "int", Asc(char), "Cdecl")
return buf
} | It can also be condensed...
| Code: | FillChar(char=" ", cnt=100) {
VarSetCapacity(buf, cnt*(A_IsUnicode ? 2:1), 1)
, DllCall("msvcrt\_" (A_IsUnicode ? "wcsset":"strset"), "str", buf, "int", Asc(char), "Cdecl")
return buf
} | ...but in that case the function name can't be resolved at load-time, so the call takes twice as long.
There are also _wcsnset and _strnset which accept a maximum count, but they still stop at the first null character (the null-terminator) so these are easier and faster. |
|
| Back to top |
|
 |
infogulch
Joined: 27 Mar 2008 Posts: 649
|
Posted: Tue Jul 20, 2010 11:49 pm Post subject: |
|
|
Awesome thanks!
I think you forgot the first part btw: | Code: | FillChar(char=" ", cnt=100) {
varsetcapacity(buf, 128), varsetcapacity(buf, 0)
if A_IsUnicode
VarSetCapacity(buf, cnt*2, 1)
, DllCall("msvcrt\_wcsset", "str", buf, "int", Asc(char), "Cdecl")
else
VarSetCapacity(buf, cnt, 1)
, DllCall("msvcrt\_strset", "str", buf, "int", Asc(char), "Cdecl")
return buf
}
FillChar(char=" ", cnt=100) {
varsetcapacity(buf, 128), varsetcapacity(buf, 0), VarSetCapacity(buf, cnt*(A_IsUnicode ? 2:1), 1)
, DllCall("msvcrt\_" (A_IsUnicode ? "wcsset":"strset"), "str", buf, "int", Asc(char), "Cdecl")
return buf
} |
_________________ Scripts - License |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Wed Jul 21, 2010 8:21 am Post subject: |
|
|
| infogulch wrote: | | I think you forgot the first part btw: | I had forgotten VarSetCapacity ignores RequestedCapacity when filling the variable. VarSetCapacity(buf, 128), VarSetCapacity(buf, 0) helps because it prevents buf from being allocated persistent memory, instead forcing the allocations to be the requested size. However, it only has an effect on the first call, then it becomes unnecessary overhead. (Edit: It should also be noted that this is undocumented behaviour and as such should not be relied upon.) Here is an alternative approach:
| Code: | FillChar(char=" ", cnt=100) {
if A_IsUnicode
VarSetCapacity(buf, cnt*2, 1), NumPut(0, buf, cnt*2, "short")
, DllCall("msvcrt\_wcsset", "str", buf, "int", Asc(char), "Cdecl")
else
VarSetCapacity(buf, cnt, 1), NumPut(0, buf, cnt, "char")
, DllCall("msvcrt\_strset", "str", buf, "int", Asc(char), "Cdecl")
return buf
} | This explicitly null-terminates the variable at the correct position. It appears to add about 9% to the benchmark time (with default parameters), whereas the redundant VarSetCapacity method adds about 60%.
I also tried a variant using:
| Code: | | VarSetCapacity(buf, cnt*2, 1) != cnt*2 ? NumPut(0, buf, cnt*2, "short") : 0 | ...but it turns out that the code to avoid the unnecessary NumPut takes about as long as the NumPut itself.  |
|
| Back to top |
|
 |
HotKeyIt
Joined: 18 Jun 2008 Posts: 4653 Location: AHK Forum
|
Posted: Wed Jul 21, 2010 10:45 pm Post subject: |
|
|
Is this a bug  | Code: | obj1:=Object()
obj2:=Object()
obj1.object:=obj2
obj1.base:=Object("__GET","TEST")
obj2.base:=Object("__GET","TEST")
MsgBox % obj1[] ;works
MsgBox % obj2[] ;works
MsgBox % obj1.object[] ;does not work
TEST(o,k=""){
MsgBox % "k = " k
} |
_________________ AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun  |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Thu Jul 22, 2010 2:03 am Post subject: |
|
|
You may consider it a bug/limitation. It is related to the following:
| Quote: | Although only a single literal parameter can be specified this way, any number of additional parameters can be specified:
| Code: | Value := Object.Param1[ Param2, Param3, ... ] ; GET
Result := Object.Param1[ Param2, Param3, ... ] := Value ; SET
Result := Object.Param1( Param2, Param3, ... ) ; CALL
| Source: Objects - Syntax - Invoking an Object
| Specifically, as obj1.object[x] would be equivalent to obj1["object",x], obj1.object[] is equivalent to obj1["object"].
For now, `(obj1.object)[] can be used to force obj1.object to be evaluated separately. (The escape character is only necessary if it is at the start of a line.) |
|
| Back to top |
|
 |
HotKeyIt
Joined: 18 Jun 2008 Posts: 4653 Location: AHK Forum
|
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Thu Jul 22, 2010 11:56 am Post subject: |
|
|
| I am considering changing it. It seems pointless to write x.y[] when it is equivalent to x.y, but I'm not sure which behaviour is more intuitive. Obviously it is more useful for [] to actually do something in that context. Another workaround: obj1["object"][] is probably cleaner than the `() method. |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|