AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

AutoHotkey_L : Arrays, Debugger, #If expression, etc.
Goto page Previous  1, 2, 3 ... 23, 24, 25 ... 28, 29, 30  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
Lexikos



Joined: 17 Oct 2006
Posts: 4469
Location: Qld, Australia

PostPosted: Tue Feb 02, 2010 11:10 pm    Post subject: Reply with quote

majkinetor wrote:
Are there any plans to add "operational" metafunctions like add, sub, pow, mul, concat, len, eq, lt, gt and so on.
Not really. I've thought about it. How should the method be chosen where only one operand is an object, or both operands are different "types" of objects?
Quote:
One additional object information that would be great to have is "default property" (VB has it for instance)
I've thought about it, and I agree. The simplest way would be for TokenToXxxx (where Xxx is String, Int64 etc) to invoke a method of the object. Memory allocation is an issue though, since these functions are normally only provided with a buffer of MAX_NUMBER_SIZE (256) bytes.
Quote:
I also wonder is it achievable to define default function call. It could come handy in various situations:
No. To allow that syntax would mean essentially throwing away validation of function names. However, you can do MyClass[p1, ... pn], which will call MyClass.base.__Get as long as p1 isn't a valid key. When an object is used as a "method" of some other object (like calling_obj.foo() where calling_obj.foo == method_obj) , it is called like method_obj[calling_obj](params) which generally calls method_obj.base.__Call since method_obj[calling_obj] wasn't assigned. (This is how MetaProps works.) Similarly, you could use any unassigned key (but this value will be passed to __Call): method_obj[""](params). If you think it would be useful, I could allow method_obj.(params). (I initially thought it seemed a bit odd/ambiguous.)
Quote:
accessing any field of Obj will crash AHKL:
Do you see an exit code? SciTE tells me -1073741571, which is 0xC00000FD; i.e. stack overflow.
Quote:
For convenience, the following two examples are equivalent:
Code:
; Explicit initialization:
obj := Object()
obj[a] := b
obj[c] := d

; In-line initialization:
obj := Object(a, b, c, d)
Source: AutoHotkey_L - Objects
In other words, Object("base", TThumb, "label", "thumb") causes MetaProps to be called (to set .label := "thumb") before obj.label exists. When MetaProps tries to access the property, it recurses. It does this repeatedly until stack overflow occurs.

To avoid triggering meta-functions, set the "base" last or use _Insert. If you think Object() should only do raw assignments, let me know. If you thinks the current behaviour is better, also let me know. (You=anyone.)

Alternatively, you can bypass meta-functions using ._Insert().
Back to top
View user's profile Send private message Visit poster's website
majkinetor



Joined: 24 May 2006
Posts: 4116
Location: Belgrade

PostPosted: Wed Feb 03, 2010 1:58 am    Post subject: Reply with quote

Quote:
How should the method be chosen where only one operand is an object, or both operands are different "types" of objects?

Let the objects handle that stuff internally. You can handle mixed expressions as:
Code:
 a, b - object, L - litteral or variable
 a + b ; a.base.__add(b)
 a + L ; a.base.__add(L)
 L + b ; b.base.__add(L)


Unary operators don't have that problem at all.

Quote:
If you think it would be useful, I could allow method_obj.(params). (I initially thought it seemed a bit odd/ambiguous.)

I would personally use such thing. (all the time) Very Happy

Code:
 If you think Object() should only do raw assignments, let me know.
.
I think current behavior is better. I was well aware of the importance of ordering, I guess it slipped true.
_________________
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 4116
Location: Belgrade

PostPosted: Wed Feb 03, 2010 2:27 pm    Post subject: Reply with quote

In R43 bellow code stopped working:

Code:
   usr32 := DllCall("GetModuleHandle", "str", "user32")
   adr := DllCall("GetProcAddress", "uint", usr32 , "str", "GetWindowLong")
   msgbox % adr " " A_LastError


The A_LastError value is always ERROR_PROC_NOT_FOUND (127)

I tried different ways of calling, using astr and A but results are always the same.
_________________
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 4469
Location: Qld, Australia

PostPosted: Wed Feb 03, 2010 2:57 pm    Post subject: Reply with quote

majkinetor wrote:
I would personally use such thing. (all the time) Very Happy
To be clear, I would only remove the requirement that the string between . and ( is not empty. I suppose it would work as follows:
Code:
func := Object("", "DefaultFunc")
func.(params)
; same as func[""](params)
DefaultFunc(this, params) {
    ...
}
__Call would work the same as for other methods, but of course the method name parameter would be an empty string.
Quote:
In R43 bellow code stopped working
I doubt it. Smile
Code:
usr32 := DllCall("GetModuleHandle", "str", "user32")
adr := DllCall("GetProcAddress", "uint", usr32 , "astr", "GetWindowLongA")
MsgBox % adr " " A_LastError
  • GetProcAddress has no separate ANSI/Unicode versions. It accepts an LPCSTR (not LPCTSTR or LPCWSTR), so is always "astr".
  • GetWindowLong really isn't a function - it's a macro for GetWindowLongA or GetWindowLongW. MSDN gives it away with "Implemented as ANSI and Unicode versions." When you call it in AutoHotkey, DllCall adds "A" or "W" when it fails to find "GetWindowLong". (I suspect you knew this but overlooked it this time.)
  • GetModuleHandle is also a macro for 'A or 'W, and accepts LPCTSTR, effectively the native string type for the current build - "str",string or "ptr",&var or "uint",&var (in current/32-bit builds).
Thanks for posting, though.
Back to top
View user's profile Send private message Visit poster's website
HotKeyIt



Joined: 18 Jun 2008
Posts: 2192
Location: GERMANY

PostPosted: Wed Feb 03, 2010 3:08 pm    Post subject: Reply with quote

Quote:
If you think it would be useful, I could allow method_obj.(params). (I initially thought it seemed a bit odd/ambiguous.)

If I understood it right, I vote for yes please Smile
Code:
method_obj.(params)
;should be the same as
method_obj[""](params)

method_obj[""][""][""](params)
;so above would be:
method_obj...(params)

;If implemented, would this be possible as well?
method_obj..key := value


That would be great Smile

Quote:
To avoid triggering meta-functions, set the "base" last or use _Insert. If you think Object() should only do raw assignments, let me know. If you thinks the current behaviour is better, also let me know. (You=anyone.)

Personally I do not care. But from a user/beginner perspective I would suggest not to use it there, unless something like this would work (I know we discussed before Smile )
Code:
a:=Object("base","test")
MsgBox % a.base

_________________
AutoHotFile - ToolTip(n,text,title,options) Wink
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 4116
Location: Belgrade

PostPosted: Wed Feb 03, 2010 6:02 pm    Post subject: Reply with quote

Lexikos wrote:
I doubt it.

I know about marcros, A, W, and other stuff plus I am sure I tried that code. I was testing with several Win APIs but I posted only that one.
One another was DefWndProc. Can you explain me why this doesn't work ? I don't know maybe I just didn't sleep right last night...

Code:
usr32 := DllCall("GetModuleHandle", "str", "user32")
adr := DllCall("GetProcAddress", "uint", usr32 , "str", "DefWindowProc")
MsgBox % adr "`n" A_LastError "`n" ErrorLevel "`n" A_AHKVersion
; 0 127 0  1.0.48.05.L43

It is equivalent to "wstr", "DefWndProcW" so it should....

Quote:
;If implemented, would this be possible as well?
method_obj..key := value

I didn't think about this, but it looks like nice syntax suggar. The extreme variant looks a bit strange (obj......func()) but I guess its better then to write obj.obj2.boj3.obj4.obj5.obj6.func() each time.

EDIT:
Ah, I see Rolling Eyes (brainwashed obviously)
Code:
adr := DllCall("GetProcAddress", "uint", usr32 , "astr", "DefWindowProcW")

I reread your post to notice color changes of one letter (which is not easy for me as I have astigmatism and am blind for some colors). I also yesterday noticed a dot after 3thd reading.
_________________
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 4469
Location: Qld, Australia

PostPosted: Wed Feb 03, 2010 10:52 pm    Post subject: Reply with quote

HotKeyIt wrote:
But from a user/beginner perspective I would suggest not to use it there,
What's better for a beginner, and why?
Quote:
unless something like this would work
Of course that should work; by "only do raw assignments" I really meant "not trigger meta-functions." If it didn't work, parameter order would no longer be an issue. That is; the rest would effectively be raw assignments since there would be no base to define alternative behaviour.

On the other hand, I was considering allowing this:
Code:
pizza := Object(food, ...)
; equivalent to
pizza := Object("base", food, ...)
This would work without ambiguity because Object() currently doesn't support an odd number of parameters (except for a lone integer parameter).
majkinetor wrote:
I didn't think about this, but it looks like nice syntax suggar.
I don't see anything "nice" or useful in it, only potential headaches.
Code:
obj["","","","",""].func()
Back to top
View user's profile Send private message Visit poster's website
majkinetor



Joined: 24 May 2006
Posts: 4116
Location: Belgrade

PostPosted: Thu Feb 04, 2010 4:08 pm    Post subject: Reply with quote

When I proposed it, I didn't think about "long dot" syntax. I am interested in calling objects as functions without container objects. In that sense, "obj.()" is the closest to that wish.
_________________
Back to top
View user's profile Send private message
HotKeyIt



Joined: 18 Jun 2008
Posts: 2192
Location: GERMANY

PostPosted: Thu Feb 04, 2010 8:34 pm    Post subject: Reply with quote

Lexikos wrote:
majkinetor wrote:
I didn't think about this, but it looks like nice syntax suggar.
I don't see anything "nice" or useful in it, only potential headaches.
Code:
obj["","","","",""].func()


You are right, after thinking about this a while I agree.
How about to support this?
Code:
obj[,,,,].func()


EDIT
Currently this looks to crash, could be [] same as [""] as well Question
Code:
a:=Object()
a[]:=1
MsgBox % a[]

_________________
AutoHotFile - ToolTip(n,text,title,options) Wink
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 4116
Location: Belgrade

PostPosted: Thu Feb 04, 2010 8:52 pm    Post subject: Reply with quote

I just want to report that I successfully ported very complex script, Multi-Rename Script to Unicode.

I want to share my impressions about it.

First, I am impressed how things work flawlessly.

One big concern, however, are DllCalls. DllCalls were failing in such measure that I spent entire day debugging and tracking which one failed and why (MRS has 20 or so modules). Because some APIs have W variants and some only A, and because str is silently converted to wstr, and because you have to use Transform ToUnicode with output str's, it can be hard to track problems to unprepared and habitual mind. I almost wished the default string format for DllCall is still astr Smile

There are also problems with direct string memory handling if you have those (I happened to have every kind of unsupported sh*it in MRS).

Then, I wanted to make sure MRS could be run with both AHK and AHKL so I introduced A_IsUnicode ? all around plus Translate( ByRef var ) function that translates to Unicode from centralized place so the only change in switching ahk branch is the need to put return at start of Translate() func (making function that doesn't depend on Transform keyword is feasible, because AHK complains about "ToUnicode").

All in all, if you need to port things the number of DllCalls and NumGets/Puts will influence the job a lot and if you need to support both AHK and AHKL its doable with single version of the script.

Finally, I am sorry if I posted bunch of stupid questions in the process Rolling Eyes
_________________
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 4469
Location: Qld, Australia

PostPosted: Thu Feb 04, 2010 10:58 pm    Post subject: Reply with quote

HotKeyIt wrote:
You are right, after thinking about this a while I agree.
How about to support this?
Code:
obj[,,,,].func()
I don't think so. It would have to be inconsistent with regular (non-dynamic) function calls, in that each optional parameter's default value would be ignored. (There's no way in advance to know what the default value of a parameter in an object-invoke should be.)
Quote:
Currently this looks to crash,
It crashes because load-time validation of the parameter count doesn't occur - the "function call" isn't determined to be ObjSet until after the parameters are processed. I've added a run-time check to Object::Invoke to compensate.
Quote:
could be [] same as [""] as well Question
That would reduce its usefulness. If you want it to work that way, the following should work (and even prevents the crash mentioned above):
Code:
a:=Object("base",Object("__Set","aset","__Get","aget"))
a[]:=1
MsgBox % a[]
MsgBox % a[""]

aset(a,b,c="!nOnE!") {
   if (c == "!nOnE!")   ; only 2 params (the object, new value)
      return a[""] := b
}
aget(a,b="!nOnE!") {
   if (b == "!nOnE!")   ; only 1 param (the object)
      return a[""]
}
I've commited a fix for the crash and updated the downloads to include this and some other fixes I had committed earlier. I'm updating my build & release process, so for now I haven't incremented the revision number. I might drop revision numbers entirely.


majkinetor, I'm glad to hear of your success. Btw, jackieku and fincs did most of the real work behind the unicode changes.
Back to top
View user's profile Send private message Visit poster's website
Tuncay



Joined: 07 Nov 2006
Posts: 897
Location: Berlin, DE

PostPosted: Thu Feb 04, 2010 11:57 pm    Post subject: Reply with quote

Quote:
I might drop revision numbers entirely.

why that? I don`t see any benefit to do this. Please do not answer with "I don`t see any benefit not doing this.".

In example, I am using one older version for just one specific script. And updating to one newer version is more risky than in mainstream Ahk. So I stay with old version. Someday it could be important to know the version number.
_________________
Download Ahk Standard Library Collection - An archive with stdlib compatible function libraries
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 4116
Location: Belgrade

PostPosted: Fri Feb 05, 2010 11:34 am    Post subject: Reply with quote

What happened with this fix ?
_________________
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 4116
Location: Belgrade

PostPosted: Fri Feb 05, 2010 3:07 pm    Post subject: Reply with quote

I have a problem with IniWrite:
Code:
IniWrite, мука, Config.ini, Конфиг, п
IniWrite, %A_AhkVersion%, Config.ini, Конфиг, ver

What I get is UTF-8 + BOM Config ini file with garbage.

I also have problem with code bellow - It works when test.ini is UTF8 but doesn't with UTF8+BOM when it returns error 2 (file not found).
Code:
   s := LoadSection("test.ini", "Config")
   m(s)
return

LoadSection( pIniFile, pSection ) {
   Loop, %pIniFile%, 0                        ; Expand relative paths, since GetPrivateProfileSection only searches %A_WinDir%.
      pIniFile := A_LoopFileLongPath
   
   VarSetCapacity(res, 0x7FFF, 0)
   s := DllCall("GetPrivateProfileSection", "str", pSection, "uint", &res, "uint", 0x7FFF, "str", pIniFile)
   if !s
      return A_LastError
   Loop, % s-1                        
      if !NumGet(res, (A_Index-1)*2, "Char")         ; Each line within the section is terminated with a null character.  Replace each delimiting null char with a newline
         NumPut(10, res, (A_Index-1)*2, "Char")      ; \0 -> \n

   VarSetCapacity(res, -1)
   return res
}


Thx for help.
_________________
Back to top
View user's profile Send private message
jackieku



Joined: 30 Nov 2008
Posts: 69

PostPosted: Fri Feb 05, 2010 3:14 pm    Post subject: Reply with quote

majkinetor wrote:
One big concern, however, are DllCalls. DllCalls were failing in such measure that I spent entire day debugging and tracking which one failed and why (MRS has 20 or so modules). Because some APIs have W variants and some only A, and because str is silently converted to wstr, and because you have to use Transform ToUnicode with output str's, it can be hard to track problems to unprepared and habitual mind. I almost wished the default string format for DllCall is still astr Smile

If the APIs are from the Windows itself, I believe almost all APIs have "W" version. (If there is no "W" version, why add "A" to the function name?) Some of them may not have "A" version (e.g. CommandLineToArgvW and many COM interfaces). Unicode is not a new thing for Windows, it just a new thing for AHK. Smile

There are some tips for DllCall() at AutoHotkeyU's wiki page.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page Previous  1, 2, 3 ... 23, 24, 25 ... 28, 29, 30  Next
Page 24 of 30

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group