AutoHotkey Community

It is currently May 26th, 2012, 9:56 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 ... 10, 11, 12, 13, 14, 15, 16 ... 70  Next
Author Message
 Post subject:
PostPosted: September 26th, 2009, 11:40 am 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
Lexikos, you are geniuos, thank you so much for new features.

Object feature is bombastic :D

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 :shock:


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 :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 27th, 2009, 12:42 am 
Offline

Joined: July 29th, 2005, 5:32 pm
Posts: 179
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. :lol:

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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 27th, 2009, 3:18 am 
Offline

Joined: July 9th, 2009, 9:25 pm
Posts: 120
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"


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 27th, 2009, 4:04 am 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
HotKeyIt wrote:
Does it mean LowLevel is fully functionally again :shock:
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.)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 27th, 2009, 9:52 am 
Offline

Joined: June 18th, 2008, 8:36 am
Posts: 4923
Location: AHK Forum
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 :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 27th, 2009, 10:39 am 
Offline

Joined: July 9th, 2009, 9:25 pm
Posts: 120
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..
    ...


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 27th, 2009, 1:36 pm 
Offline

Joined: November 7th, 2006, 9:47 pm
Posts: 1934
Location: Germany
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 September 27th, 2009, 3:46 pm, edited 1 time in total.

Report this post
Top
 Profile  
Reply with quote  
PostPosted: September 27th, 2009, 3:42 pm 
Offline

Joined: January 29th, 2009, 9:50 pm
Posts: 483
Location: Belgium
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? :?: :idea:
or i keep searching for a while for a convertion. :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject: array clarification
PostPosted: September 27th, 2009, 6:56 pm 
Offline

Joined: August 3rd, 2007, 8:01 am
Posts: 555
Location: Houston, TX
Lexikos wrote:
Revision 31 - September 26, 2009
Object/array support

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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 28th, 2009, 7:26 am 
Offline

Joined: July 9th, 2009, 9:25 pm
Posts: 120
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())


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 28th, 2009, 2:31 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
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.)


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 28th, 2009, 2:56 pm 
Offline

Joined: November 7th, 2006, 9:47 pm
Posts: 1934
Location: Germany
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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 28th, 2009, 8:17 pm 
Offline
User avatar

Joined: May 24th, 2009, 5:35 am
Posts: 2099
Location: Iowa, USA
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.

_________________
Image
Recommended: AutoHotkey_L
Basic Webpage Controls


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 28th, 2009, 9:01 pm 
Offline

Joined: July 9th, 2009, 9:25 pm
Posts: 120
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 :lol: 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 October 1st, 2009, 9:17 am, edited 11 times in total.

Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: September 28th, 2009, 11:22 pm 
Offline

Joined: October 17th, 2006, 4:15 pm
Posts: 7502
Location: Australia
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.


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 ... 10, 11, 12, 13, 14, 15, 16 ... 70  Next

All times are UTC [ DST ]


Who is online

Users browsing this forum: No registered users and 1 guest


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