 |
AutoHotkey Community Let's help each other out
|
AutoHotkey_L: Arrays, Debugger, x64, COM, #If expression ...
Goto page Previous 1, 2, 3 ... 12, 13, 14 ... 68, 69, 70 Next
|
| View previous topic :: View next topic |
| Author |
Message |
HotKeyIt
Joined: 18 Jun 2008 Posts: 4653 Location: AHK Forum
|
Posted: Sat Sep 26, 2009 10:40 am Post subject: |
|
|
Lexikos, you are geniuos, thank you so much for new features.
Object feature is bombastic
I like A ~=B, hope it will be kept in future
| Lexikos wrote: | | Fixed: An incompatibility with LowLevel. | Does it mean LowLevel is fully functionally again
Edit:
Looks like strings and digits are threated differently:
| Code: | table:=Object("1",1,2,2)
Msgbox % "a " table.1 "`nb " table["1"] "`nc " table[1] "`n`nd " table.2 "`ne " table["2"] "`nf " table[2] |
Is there possibly a way to enumerate trough items in the object?
Do you possibly intend to change AutoHotkey commands to support objects or will there be internal functions to do that or should we start to write functions (where possible)?
| Code: | table:=Object(1,1,2,2)
loop,Parse,table
MsgBox % A_LoopField
ExitApp
;or
table:=Object()
string=s.t.r.i.n.g
StringSplit,table,string,.
Msgbox % table.1 "`n" table.2 |
It looks like it is not possible to use an object as variable and the object gets inaccessible if done so?
I think this should be noted in helpfile, so it would be clever to use # _ @ $ in object variables.
| Code: | table:=Object(1,1)
Msgbox % table.1 |
Here the object seems to be broken
| Code: | table:=Object(1,1)
table.a := 1
table=test
Msgbox % table "." table.a |
_________________ AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun  |
|
| Back to top |
|
 |
freakkk
Joined: 29 Jul 2005 Posts: 179
|
Posted: Sat Sep 26, 2009 11:42 pm Post subject: |
|
|
Lexikos, legendary release! I will have to study/experiment before I can give some intelligible feedback on the object implementation. Hopefully I won't spontaneously feel like re-writing everything I've ever written in AHK.
| Lexikos wrote: | | Quote: | - Added: A ~= B; equivalent to RegExMatch(A, B). May be removed in a future revision (feedback wanted).
|
| Do you have any thoughts/plans to implement a means to retrieve any meaningful output, such as FoundPos, or any captured subpatterns? If not, then I suppose I will probably tend to stick to the regexmatch function call. Although, it wouldn't hurt to leave in place since that is a standard syntax for RE (at least in perl). _________________ .o0[ corey ]0o. |
|
| Back to top |
|
 |
temp01
Joined: 09 Jul 2009 Posts: 120
|
Posted: Sun Sep 27, 2009 2:18 am Post subject: |
|
|
| freakkk wrote: | | Lexikos wrote: | | Quote: | - Added: A ~= B; equivalent to RegExMatch(A, B). May be removed in a future revision (feedback wanted).
|
| Do you have any thoughts/plans to implement a means to retrieve any meaningful output, such as FoundPos, or any captured subpatterns? |
~= returns the foundpos:
| Code: | | Msgbox % "ab33c"~="\d" |
|
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Sun Sep 27, 2009 3:04 am Post subject: |
|
|
| HotKeyIt wrote: | Does it mean LowLevel is fully functionally again  | Most or all of the LowLevel functions which work with v1.0.48 should work. I've also updated DebugBif() for L31 compatibility.
| Quote: | | Looks like strings and digits are threated differently: | That is due to pre-existing AutoHotkey behaviour - quoted literals are considered purely non-numeric. Why quote a numeric literal if you want it to be treated as a number rather than a string?
| Quote: | | Is there possibly a way to enumerate trough items in the object? | Not really (yet). However, for "conventional" arrays, _MinIndex and _MaxIndex can be used:
| Code: | arr := Object(0,"zero", 1,"one", 2,"two", 4,"four")
; for A_Index = 1.._MaxIndex()
Loop % arr._MaxIndex()
MsgBox % arr[A_Index]
; for i = _MinIndex().._MaxIndex()
i := arr._MinIndex()
While i <= arr._MaxIndex()
MsgBox % arr[i++]
|
| Quote: | | Do you possibly intend to change AutoHotkey commands to support objects or will there be internal functions to do that or should we start to write functions (where possible)? | I do not intend to update commands; though they could accept objects via variables, it might seem inconsistent since objects aren't supported by the traditional, non-expression syntax. Changing commands to use objects unconditionally would reduce backward-compatibility, remove some useful functionality and in some cases reduce performance. "Overloading" them to use an object if present might be too obscure; by contrast, having a distinct function() would make the difference in behaviour obvious.
I was thinking that RegExMatch could output its results to an object if one is present in UnquotedOutputVar. (It would be less obscure than for StringSplit since in-line assignment is possible: RegExMatch(A,B,C:=Object()).) I may also implement SplitStr() as a function. For now they can be written as script functions (with a little difficulty in the case of RegExMatch).
Can you think of any commands that would really benefit from it other than StringSplit?
| Quote: | table:=Object(1,1,2,2)
loop,Parse,table
MsgBox % A_LoopField
| I'm not in favour of re-using a parsing loop since it doesn't really make sense.
| Quote: | | It looks like it is not possible to use an object as variable and the object gets inaccessible if done so? | I am not able rightly to apprehend the kind of confusion of ideas that could provoke such a question. An object is merely a value which may be stored in a variable. Would you expect a variable to keep its previous string contents after you assign it a number?
| Quote: | | I think this should be noted in helpfile, | I think it is already implied by the following:
| Quote: | In addition to strings and numbers, AutoHotkey_L supports objects. Objects are distinct from other types of values and can be stored in variables, passed to or returned from functions and stored in other objects.
Source: AutoHotkey_L - Objects |
| Quote: | | so it would be clever to use # _ @ $ in object variables. | I disagree. IMO, a variable's name should reflect it's meaning or usage, which should imply the type of value it holds. If you don't know what a variable is used for, you don't need to know what type of value it contains. Additionally, I think those symbols don't really imply "object". (If you wish to prefix variables in this way I have no objections, but I will not recommend it.) |
|
| Back to top |
|
 |
HotKeyIt
Joined: 18 Jun 2008 Posts: 4653 Location: AHK Forum
|
Posted: Sun Sep 27, 2009 8:52 am Post subject: |
|
|
| Lexikos wrote: | | Quote: | | Looks like strings and digits are threated differently: | That is due to pre-existing AutoHotkey behaviour - quoted literals are considered purely non-numeric. Why quote a numeric literal if you want it to be treated as a number rather than a string?
|
| Code: | table:=Object(1 . 1,1)
Msgbox % table.11 "." table[11] |
Since this works it is not a problem
| Lexikos wrote: |
Can you think of any commands that would really benefit from it other than StringSplit?
|
StringSplit and RegExMatch looks to be the only commands where we would really benefit from.
| Lexikos wrote: |
| Quote: | table:=Object(1,1,2,2)
loop,Parse,table
MsgBox % A_LoopField
| I'm not in favour of re-using a parsing loop since it doesn't really make sense.
|
I thought this could enumerate trough the objects and A_LoopField would contain nextkey. _________________ AHK_H (2alpha) AHF TT _Struct WatchDir Yaml _Input ObjTree RapidHotkey DynaRun  |
|
| Back to top |
|
 |
temp01
Joined: 09 Jul 2009 Posts: 120
|
Posted: Sun Sep 27, 2009 9:39 am Post subject: |
|
|
| Lexikos wrote: | | Can you think of any commands that would really benefit from it other than StringSplit? |
If..in/contains ?
| Code: | ; if there's value that matches exactly abc or def e.g. if ObjVar := Object("x", "abc")
If ObjVar contains abc,def
...
; match keys instead of values
If "x" in Obj ; this breaks the current (If Var in Literal/Expression) format though..
... |
|
|
| Back to top |
|
 |
Tuncay
Joined: 07 Nov 2006 Posts: 1886 Location: Germany
|
Posted: Sun Sep 27, 2009 12:36 pm Post subject: |
|
|
Very interesting release!
| Quote: | | Added: A ~= B; equivalent to RegExMatch(A, B). May be removed in a future revision (feedback wanted). |
Thats a long waited feature to me. Hope Chris implements it in mainstream Ahk. Please don`t overlaod it. The simplicity and performance are main reason to use it. I love it. Not tested yet, hope ErrorLevel will be not changed also. +10/10
Here are some thoughts/wishes about that:
What about subpatterns here? Are they lost? I suggest that it should. Or they could be saved in variables 1 to xxx... very bad.
But at named subpatterns:
| Code: | | A ~= "(?P<Year>\d{4})" |
may could create variable Year directly.
Example:
| Code: | If ("a1234bc" ~= "(?P<Year>\d{4})")
MsgBox %Year% |
Lexikos, I like you very much. Really.
-------------------
EDIT: my bad all ok
Last edited by Tuncay on Sun Sep 27, 2009 2:46 pm; edited 1 time in total |
|
| Back to top |
|
 |
emmanuel d
Joined: 29 Jan 2009 Posts: 436 Location: Belgium
|
Posted: Sun Sep 27, 2009 2:42 pm Post subject: Get iconpath and nr from h_icon |
|
|
how can i implement h_icon in:
| Code: |
SendMessage, 0x7F, 1, 0,, ahk_id %wid%
h_icon := ErrorLevel
if ( ! h_icon )
{
SendMessage, 0x7F, 2, 0,, ahk_id %wid%
h_icon := ErrorLevel
if ( ! h_icon )
{
SendMessage, 0x7F, 0, 0,, ahk_id %wid%
h_icon := ErrorLevel
if ( ! h_icon )
{
; GCL_HICON (-14)
h_icon := DllCall( "GetClassLong", "uint", wid, "int", -14 )
if ( ! h_icon )
{
; GCL_HICONSM (-34)
h_icon := DllCall( "GetClassLong", "uint", wid, "int", -34 )
if ( ! h_icon )
{
; IDI_APPLICATION 32512
h_icon := DllCall( "LoadIcon", "uint", 0, "uint", 32512 )
}
}
}
}
}
;now i have h_icon.
;how can i use it in the menu?
menu,Tasks,icon,SomeTitle,%h_icon%,,16
|
i searched the forums but there is no way i know off to get the icon(exe)path,and nr from h_icon
is it posible to support h_icon in the menu?
or i keep searching for a while for a convertion.  |
|
| Back to top |
|
 |
tinku99
Joined: 03 Aug 2007 Posts: 513 Location: Houston, TX
|
Posted: Sun Sep 27, 2009 5:56 pm Post subject: array clarification |
|
|
Perhaps you should clarify that these object based arrays are still just associative arrays.
I am still waiting for syntactic sugar for numput and numget, ie. real, fixed, in memory contiguous arrays, that can be referenced using index arithmetic and without a binary search, and that allow binary values.
I wonder how hard it would be to modify your implementation to create more c like arrays.
In the meantime, I am sure these arrays will still be useful.
Thank you, Lexikos. |
|
| Back to top |
|
 |
temp01
Joined: 09 Jul 2009 Posts: 120
|
Posted: Mon Sep 28, 2009 6:26 am Post subject: |
|
|
| Tuncay wrote: | But at named subpatterns:
| Code: | | A ~= "(?P<Year>\d{4})" |
may could create variable Year directly. |
+1
Or A_LastMatch maybe?
| Code: | If ("200910" ~= "(\d{4})(?<Month>\d{2})"){
MsgBox, Year: %A_LastMatch1%
MsgBox, Month: %A_LastMatchMonth%
} |
Edit: Or
| Code: | If ("200910" ~= "(\d{4})(?<Month>\d{2})"){
MsgBox, % "Year: " A_LastMatch[1]
MsgBox, % "Month: " A_LastMatch["Month"]
} |
So basically, make A~=B equivalent to RegExMatch(A, B, A_LastMatch:=Object()) |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Mon Sep 28, 2009 1:31 pm Post subject: |
|
|
Thanks for the input.
| HotKeyIt wrote: | | I thought this could enumerate trough the objects and A_LoopField would contain nextkey. | I got that. My point was that since it doesn't do any parsing, it would not make sense to use "Loop, Parse".
| temp01 wrote: | | If..in/contains ? | I think that your examples are inconsistent with the current semantics of If..in/contains, and that any implementation supporting objects will probably be ambiguous and not necessarily intuitive. However, I recognize that the functionality could be very useful so I'll consider implementing less ambiguous methods - e.g. obj._HasValue(v) or obj._KeyOfValue(v). The latter seems more useful. _HasValue(v) would be equivalent to _KeyOfValue(v)!="", except that "" is actually a valid key.
Perhaps it should be considered further if/when in/contains become supported in expressions, since they necessarily won't be consistent with the current syntax.
| Quote: | ; match keys instead of values
If "x" in Obj | That would be equivalent to Obj.x!="" since assigning an empty string removes the item and its key. That is, unless "If in" (or whatever) bypasses the meta-mechanism; I'm not sure whether that would be intuitive.
| Tuncay wrote: | | The simplicity and performance are main reason to use it. I love it. Not tested yet, hope ErrorLevel will be not changed also. ... What about subpatterns here? | I think it is simpler than you realise: When I said A ~= B is equivalent to RegExMatch(A, B), I meant it precisely, not figuratively. It is nothing more than syntax sugar which is processed entirely at load-time. The two should not behave or perform any differently.
I'm reluctant to changes its functionality, partly because I think an operator's purpose and effect should be very clear (i.e. with no hidden side-effects, though ~= does set ErrorLevel) but moreso because I think its usefulness is too limited to justify spending much time on it. In fact, I spent approximately two minutes coding ~=, having already done something similar (translation of x[y]:=z to ObjSet(x,y,z)).
| Quote: | | But at named subpatterns: ... may could create variable Year directly. | That's an interesting suggestion, but I think it contradicts your earlier points about simplicity and not overloading ~=.
| emmanuel d wrote: | | is it posible to support h_icon in the menu? | It is not currently possibly. I had considered supporting it indirectly by extending LoadPicture (which is used by various commands) to accept an icon or bitmap handle. Since there didn't seem to be much demand for it, it "slipped off the list". I'll reconsider adding it in a future revision. Until then, you may use MI.ahk, which can accept either an icon handle (HICON) or filename. AHKControl uses it for a purpose similar to what you've shown.
| tinku99 wrote: | | Perhaps you should clarify that these object based arrays are still just associative arrays. | I would think it should be clear enough from the title "Associative Arrays", the (hopefully) consistent references to "keys" rather than "indices" and the fact that "[integer] keys do not need to be contiguous". Anyway, why do you say "still just associative arrays"; why should they be anything else?
| Quote: | | I wonder how hard it would be to modify your implementation to create more c like arrays. | It shouldn't be too difficult; just extend the IObject interface or ObjectBase class.
I'd like to implement C-like user-defined structs, but I'm not confident that built-in functionality would be justified. Implementing it in script would be feasible, perhaps even easier (though less efficient) than in C++.
| Quote: | | and that allow binary values. | Objects are binary values, and may also be written around "proper" binary arrays (i.e. with GlobalAlloc).
String fields in an object expand in the same way that a variable expands - when necessary, to avoid some repeated reallocations as strings of different lengths are assigned. (I realise I should try to work this into the documentation.) They could also be used to store binary data in the same way as variables, by extending _SetCapacity and adding _GetAddress. Actually, there's already code for it in L31, but it's commented out. It seemed to me that at the cost of added code and documentation size, its only benefit over simply storing a pointer returned by DllCall was that no extra code was needed to automatically manage the memory.
Oh! Now that I think of it, an important feature slipped my mind while I was writing the documentation. After the last reference to an object is released, the __Delete meta-function is invoked. If the object has no references after the function returns, it is deleted.
| Code: | obj := Object("base", Object("__Delete", "x_Delete"))
obj.ptr := DllCall("GlobalAlloc", "uint", 0, "uint", 1024)
x_Delete(obj) {
if p := obj.ptr
DllCall("GlobalFree", "uint", p)
ListLines
Pause
} |
| temp01 wrote: | | So basically, make A~=B equivalent to RegExMatch(A, B, A_LastMatch:=Object()) | That's an example of a hidden side-effect, which I'd prefer to avoid. Also, typing RegExMatch out in full allows for much shorter or more meaningful variable names.
| Chris wrote: | | However, I'm disappointed that I wasn't invited to participate in the analysis and design for these major new features. | I hope you didn't take it personally. My thoughts are usually focused on the nitty-gritty of implementation rather than the larger picture, so I tend not to do much formal "analysis and design." I'm also a natural loner. (I'd like to have replied sooner, but I was at a loss for words.) |
|
| Back to top |
|
 |
Tuncay
Joined: 07 Nov 2006 Posts: 1886 Location: Germany
|
Posted: Mon Sep 28, 2009 1:56 pm Post subject: |
|
|
| Lexikos wrote: | I think it is simpler than you realise: When I said A ~= B is equivalent to RegExMatch(A, B), I meant it precisely, not figuratively. It is nothing more than syntax sugar which is processed entirely at load-time. The two should not behave or perform any differently.
I'm reluctant to changes its functionality, partly because I think an operator's purpose and effect should be very clear (i.e. with no hidden side-effects, though ~= does set ErrorLevel) but moreso because I think its usefulness is too limited to justify spending much time on it. In fact, I spent approximately two minutes coding ~= |
I am dissapointed in that. The "suggestion" about named subpatterns was just an idea to discuss, not a direct wish. ErrorLevel should not be changed, because it is not a function call. You are right about sideeffects, no sideeffect should be existing with operators.
If it is a simple "macro replace", then the usefullness is not that great I was thinking. |
|
| Back to top |
|
 |
jethrow
Joined: 24 May 2009 Posts: 1907 Location: Iowa, USA
|
Posted: Mon Sep 28, 2009 7:17 pm Post subject: |
|
|
First off, I'd like to say: Amazing Release! Thank you for your work. I had been highly anticipating this implementation.
Now I was wondering (please forgive me if this is a ignorant question), is it at all possible (or will it be possible) to create a COM object - or use this syntax with a COM object? Something like: | Code: | pwb := object()
pwb := COM_CreateObject("InternetExplorer.Application")
pwb.Visible = "True" |
To the best of my understanding this creates two separate objects, and would dereference the AHK object - therefore destroying it. _________________
- in case I forgot to smile
Basic Webpage Controls
COM Object Reference |
|
| Back to top |
|
 |
temp01
Joined: 09 Jul 2009 Posts: 120
|
Posted: Mon Sep 28, 2009 8:01 pm Post subject: |
|
|
| jethrow wrote: | | Now I was wondering (please forgive me if this is a ignorant question), is it at all possible (or will it be possible) to create a COM object - or use this syntax with a COM object? Something like |
You'll have to rewrite the whole COM.ahk to support objects for that or create a wrapper
Demo (Edit: See COMo - Object oriented COM for latest version):
| Code: | COM_Init()
SC := COMo(COM_CreateObject("MSScriptControl.ScriptControl"))
SC.Language := "JScript"
Msgbox % SC.Eval("var arr = [4, 5]; arr[0] * arr[1] + 4")
SC.Language := "VBScript"
Msgbox % SC.Eval("Hex(43)")
SC := "" ; free it!
COM_Term()
; -- COMo Functions
COMo_GetVal(obj, name){
global COM_VT
Ret := COM_Invoke(obj.COMObj, name)
If COM_VT=9 ; thanks Lex!
Return COMo(Ret)
Else
Return Ret
}
COMo_SetVal(obj, name, val){
return COM_Invoke(obj.COMObj, name "=", val)
}
COMo_Call(obj, func, prm0="vT_NoNe",prm1="vT_NoNe",prm2="vT_NoNe",prm3="vT_NoNe",prm4="vT_NoNe",prm5="vT_NoNe"){
global COM_VT
Ret := COM_Invoke(obj.COMObj, func, prm0, prm1, prm2, prm3, prm4, prm5)
If COM_VT=9
Return COMo(Ret)
Else
Return Ret
}
COMo(param){
static COBase
If !COBase
COBase := Object("__Get", "COMo_GetVal", "__Set", "COMo_SetVal", "__Call", "COMo_Call", "__Delete", "COMo_Delete")
If param is not integer
param := COM_CreateObject(param)
Return Object("COMObj", param, "base", COBase)
}
COMo_Delete(obj){
COM_Release(obj.COMObj)
} |
This works too:
| Code: | COM_Init()
IE := COMo("InternetExplorer.Application")
IE.Visible := 1
IE.Navigate2("http://www.google.com/")
Sleep 6000
IE.Quit()
IE := ""
COM_Term() |
Or | Code: | COM_Init()
sa := COMo("Shell.Application")
Loop, % sa.Windows.Count {
win := sa.Windows.Item(A_Index-1)
out .= win.LocationName " -- " win.LocationURL "`n"
}
Msgbox,,Explorer Windows, %out%
sa := win := "" ; free sa and the last win before COM_Term()
COM_Term() |
Lex, Any reason why @, # are not allowed in dotted identifiers? I was going to use ShellApp.@Windows.Count but that doesn't work. An alternative is ShellApp["@Windows"] but then I can't use the same character for function calls.. because SA["@Item"](..) calls __Get for @Item while SA.Item(..) calls __Call
Edit: Updated with Lexikos' suggesions below (COM_VT and static base).
Last edited by temp01 on Thu Oct 01, 2009 8:17 am; edited 11 times in total |
|
| Back to top |
|
 |
Lexikos
Joined: 17 Oct 2006 Posts: 7299 Location: Australia
|
Posted: Mon Sep 28, 2009 10:22 pm Post subject: |
|
|
| Tuncay wrote: | | The "suggestion" about named subpatterns was just an idea to discuss, not a direct wish. | Understood. I discussed, did I not?
| Quote: | | ErrorLevel should not be changed, because it is not a function call. | I agree. I'll consider changing it, though it would require more time than I'd like.
| Quote: | | If it is a simple "macro replace", then the usefullness is not that great I was thinking. | My thought from the beginning has been that it isn't very useful; removing the ErrorLevel side-effect won't change that.
| temp01 wrote: | | Lex, Any reason why @, # are not allowed in dotted identifiers? | I figured it was best to limit the character set initially and expand it if absolutely necessary, rather than breaking scripts as I've had to do for variable names.
| Quote: | | but then I can't use the same character for function calls | For now you may use ObjCall.
| Quote: | | SA["@Item"](..) calls __Get for @Item while SA.Item(..) calls __Call | I haven't had time to implement method-calls with []; I plan to in a future revision.
| Quote: | COMo(param){
COBase := Object("__Get", "COMo_GetVal", "__Set", "COMo_SetVal", "__Call", "COMo_Call", "__Delete", "COMo_Delete")
...
return CO
} | Note that it creates a new base object each time. I hope that in a future revision, it will be a simple matter of prepending "static" (with no need for "if !COBase ... COBase :=").
| Quote: | | CO := Object(), CO.COMObj := param, CO.Base := COBase | I'd understand if you find it easier to follow this way, but note that the shorter method should also be marginally faster:
| Code: | | CO := Object("COMObj", param, "base", COBase) |
| Quote: | If InStr(func, "_")=1
return COMo(COM_Invoke(obj.COMObj, SubStr(func,2), prm0, prm1, prm2, prm3, prm4, prm5)) | IIRC, the global variable COM_VT should be 9 if COM_Invoke's return value is an object. Using that, wrapping objects can be automatic, and reliable when a function may or may not return an object. |
|
| 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
|