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 

Class library (OOP) - Help Thread
Goto page Previous  1, 2, 3, 4, 5, 6, 7  Next
 
Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
bmcclure



Joined: 24 Nov 2007
Posts: 774

PostPosted: Sun May 24, 2009 11:34 am    Post subject: Reply with quote

I like that idea. I preferred the original function names, but now I see the logic in changing them anyhow. Thanks for the reply!
_________________
Ben

My Trac projects
My Wiki
[Broken] - My music
Back to top
View user's profile Send private message
animeaime



Joined: 04 Nov 2008
Posts: 1045

PostPosted: Sun May 24, 2009 11:56 am    Post subject: Reply with quote

Well, in most cases, you will probably be calling the functions directly via their class name function, not the interface ones, right? The main thing I'm hoping from interfaces is to create a "standard" (like LogI, IniFileI, etc.); then, users would implement these classes making their own additions. The interfaces would be updated with additional functions as the need for such functions arise.

Since the class would implement the respective interface, you know that the core functionality remains consistent between the classes. Therefore, it would be easy to test out the different implementations and see which one does what you want.

The fact that interfaces would have the "I' says immediately that they are interfaces. I didn't use an "I" for the List interface, because I was using the Java List interface as a basis and wanted to preserve the naming. Also, with Array and Vector already devolped, there is no need for a "list" class.
_________________
As always, if you have any further questions, don't hesitate to ask.

Add OOP to your scripts via the Class Library. Check out my scripts.
Back to top
View user's profile Send private message Send e-mail
bmcclure



Joined: 24 Nov 2007
Posts: 774

PostPosted: Sun May 24, 2009 6:01 pm    Post subject: Reply with quote

So how far do you go building functionality into the interface, as opposed to leaving the functionality for the calling class to implement?

Most of my DOM interfaces, probably because they didn't start off as interfaces, handle almost all of the processing internally, and really only require the calling class to construct the actual objects and add any non-official DOM functions. Should I be moving the functions out to the calling class and just referencing them from the interface, as is seen in Coin (save for its single static function)? Or is it acceptable to keep a large number of statics in an interface?
_________________
Ben

My Trac projects
My Wiki
[Broken] - My music
Back to top
View user's profile Send private message
animeaime



Joined: 04 Nov 2008
Posts: 1045

PostPosted: Sun May 24, 2009 10:49 pm    Post subject: Reply with quote

bmmclure wrote:
So how far do you go building functionality into the interface, as opposed to leaving the functionality for the calling class to implement?

An interface is meant to be a shell. For example, the List interface defines functions which are used to manipulate lists. Then, the implementing classes (e.g. Array and Vector) implement these functions.

The only functions that should be defined in the interface are functions that are "final" (using java terminology). A final function is a function that can't be overridden. For example, the List_copy function is defined directly, because it performs the necessary task - there is no need to override it.

An interface, by design, is meant to "share" functionality. It is meant to define functions which a set of similar classes share.

bmmclure wrote:
Most of my DOM interfaces, probably because they didn't start off as interfaces, handle almost all of the processing internally, and really only require the calling class to construct the actual objects and add any non-official DOM functions. Should I be moving the functions out to the calling class and just referencing them from the interface?

I'm not sure I understand the question, but if you are asking if you should be creating an interface that implements the functions, I can only ask 1) what would the implementing class implement, and 2) why not just keep it as a class?

Interfaces, and inheritence, when added, have the overhead of a dynamic call and the function call to Class_call / Class_Scall. These functions must "figure out" which class to call. Did you run the two examples of the List_test (List_test1.ahk and List_test2.ahk)? If not, I would suggest doing so - this shows the added overhead in using interface functions.

bmmclure wrote:
Or is it acceptable to keep a large number of statics in an interface?

By statics, do you mean static functions. If so, static functions should be "rare"; at least, in my programming experience, rarely do I need a static function. For example, the getWorth function is static because a nickel, regardless, is worth 5 cents. Also, by making it a function (instead of, maybe, a constant in the constant function), it can be used as the "useFunction" paramater of the get and getAddress functions in the list interface (and implementing classes). For example, this is used in the CoinPurse object, to return the total amount of money in the CoinPurse via its getWorth function, which in turn uses the getWorth function in the coin interface.
_________________
As always, if you have any further questions, don't hesitate to ask.

Add OOP to your scripts via the Class Library. Check out my scripts.
Back to top
View user's profile Send private message Send e-mail
bmcclure



Joined: 24 Nov 2007
Posts: 774

PostPosted: Mon May 25, 2009 2:38 am    Post subject: Reply with quote

Thanks, that clears it up. I just need to further separate my logic from the interface and implement that in the classes.

The reason I'm using interfaces at all for the DOM is to follow the DOM specification... I want to create interfaces, and a set of default implementing classes, but allow anyone to create their own implementing classes however they see fit, as well.

Some of the interfaces truly need to be interfaces to function properly, I believe. Most of them directly correspond to real objects, however, and are just made into interfaces to separate the definition of the functions from the actual implementation of them.

I'm seeing the use in moving almost all of my logic outside of the interface and leaving it a shell, as it should be. Thanks again for helping clear that up.
_________________
Ben

My Trac projects
My Wiki
[Broken] - My music
Back to top
View user's profile Send private message
bmcclure



Joined: 24 Nov 2007
Posts: 774

PostPosted: Sun May 31, 2009 7:04 am    Post subject: Reply with quote

What about the possibility of supporting just the function name (with no Class name and underscore) for the FunctionName parameter of Class_call?

That would make it more useful to be able to call other classes without knowing the class name.

For instance, my DOM class needs to call a certain function within the class of an object it is passed in one of its methods.

Rather than calling Class_getClassName and then manually creating the function string, I'd like to be able to just do something like:
Code:
Class_call("canSet", Object, param1, param2, etc...)


Currently this will throw an error. Instead of a check to make sure there is an underscore in the name, perhaps there should just be a function to remove everything before the underscore in the function name to normalize it, and then figure out which class to call and append the class name and underscore again?
_________________
Ben

My Trac projects
My Wiki
[Broken] - My music
Back to top
View user's profile Send private message
animeaime



Joined: 04 Nov 2008
Posts: 1045

PostPosted: Sun May 31, 2009 9:04 pm    Post subject: Reply with quote

bmmclure wrote:
perhaps there should just be a function to remove everything before the underscore in the function name to normalize it, and then figure out which class to call and append the class name and underscore again?

The reason it throws an error is that Class_call and Class_Scall have checks to verify that the specified class object implements the class specified by the function name. That's why interface functions pass A_ThisFunc for the first parameter. Since the function name is File_Func and File is the name of the interface, everything up to the first "_" is the interface name. Then, it verifies the specified object / class implements the interface.

However, I can write another function, without this check - how about "invoke" (as seen in the COM library).

Code:
Class_invoke(Object, "canSet", param1, param2, etc...)

This would call the canSet function in the class (as specified by Object). It would still make use of the reserved value ("C1@5s", internally, because it needs to know how many parameters are passed, so that only that number of parameters are passed in the dynamic call.


Since interfaces are just starting, should I reverse the parameters (object, then paramater) to have them match the format used by COM_Invoke (for consistency)? This would apply to the newly added functions Class_invoke and Class_Sinvoke and the existing Class_call and Class_Scall. This will break scripts that use Class_call and Class_Scall, but since interfaces just began, if the change is made, now is better than later. Also, it only affects the interfaces themself - not the calling of an interface function. So, it would be very easy to modify.
_________________
As always, if you have any further questions, don't hesitate to ask.

Add OOP to your scripts via the Class Library. Check out my scripts.


Last edited by animeaime on Mon Jun 01, 2009 6:10 pm; edited 1 time in total
Back to top
View user's profile Send private message Send e-mail
bmcclure



Joined: 24 Nov 2007
Posts: 774

PostPosted: Mon Jun 01, 2009 2:57 am    Post subject: Reply with quote

I've been debating whether or not I think that the order of the parameters of Class_call should be changed, actually, and now that you bring it up, it seems like a good idea. It follows the normal OOP order of object.function(parameters).

I'm using Class_call in about 25 interfaces right now, but it would be a simple search and replace operation in each of them.
_________________
Ben

My Trac projects
My Wiki
[Broken] - My music
Back to top
View user's profile Send private message
animeaime



Joined: 04 Nov 2008
Posts: 1045

PostPosted: Mon Jun 01, 2009 4:24 am    Post subject: Reply with quote

Ok. sorry about that. I modified Class_call and Class_Scall to have ClassObject then FunctionName as the inputted parameters. Also, I added Class_invoke and Class_Sinvoke. The error messages match the ones from Class_call; "-3" is the error level (using the return from Class_callError) if the passed object isn't a class object (e.g. 0 or the empty string was passed).

For all four functions, you can call Class_callError to see if the call resulted in an error, and the error (if any, or 0 otherwise) will be returned. I've update the page on Interfaces to reflect the changed parameter order. I'll add a page for Class_invoke / Class_Sinvoke shortly.

The List and Coin interface were updated to use the new syntax. I used the below RegEx to swap the two parameters. This will swap the first two parameters for all Class_call and Class_Scall functions. It assumes that "A_ThisFunc" is the first parameter, which it should be if you followed the format used in the List and Coin interface.

Code:
;spacing (around parameters) and name for the second parameter are maintained.
;This RegEx works for both Class_call and Class_Scall
Find: (Class_S?call)\((\s*)(A_ThisFunc)(\s*),(\s*)(\w+)(\s*)(\)|,)
Replace: $1($2$6$4,$5$3$7$8


Download the updated zip.
_________________
As always, if you have any further questions, don't hesitate to ask.

Add OOP to your scripts via the Class Library. Check out my scripts.


Last edited by animeaime on Mon Jun 01, 2009 6:14 pm; edited 1 time in total
Back to top
View user's profile Send private message Send e-mail
bmcclure



Joined: 24 Nov 2007
Posts: 774

PostPosted: Mon Jun 01, 2009 5:46 pm    Post subject: Reply with quote

Modified the replacement value for backslashes instead of dollar signs, and the regex worked perfectly in EmEditor on all of my DOM interfaces at once Smile Thanks for that.

And thanks also for invoke. I haven't been able to test yet, but I'm using it as required already in the DOM.
_________________
Ben

My Trac projects
My Wiki
[Broken] - My music
Back to top
View user's profile Send private message
bmcclure



Joined: 24 Nov 2007
Posts: 774

PostPosted: Mon Jun 01, 2009 7:45 pm    Post subject: Reply with quote

Is it possible for invoke to accept the function name as a string instead of a ByRef?

To get a parameter of an object from an external class, I'd like to be able to pass Class_invoke(Object, "getSomeParam"), for instance. Right now it throws an error because it's looking for a variable reference instead.
_________________
Ben

My Trac projects
My Wiki
[Broken] - My music
Back to top
View user's profile Send private message
animeaime



Joined: 04 Nov 2008
Posts: 1045

PostPosted: Mon Jun 01, 2009 8:03 pm    Post subject: Reply with quote

bmmclure wrote:
Is it possible for invoke to accept the function name as a string instead of a ByRef?

The function name isn't ByRef - the parameters are, though. Is this what you meant?

The parameters are ByRef so that if you call a function that has any ByRef parameters, calling the function via Class_invoke will work as expected.

I can change this, so that the parameters are no longer ByRef; however, this would mean Call_invoke won't work correctly when calling a function with ByRef parameters. However, it will allow calling Class_invoke by passing a value, instead of only allowing variable references.

This is the function's signature

Code:
Class_invoke(ClassObject, FunctionName, ByRef arg1 = "C1@5s", ByRef arg2 = "C1@5s", ByRef arg3 = "C1@5s", ByRef arg4 = "C1@5s", ByRef arg5 = "C1@5s", ByRef arg6 = "C1@5s")

_________________
As always, if you have any further questions, don't hesitate to ask.

Add OOP to your scripts via the Class Library. Check out my scripts.
Back to top
View user's profile Send private message Send e-mail
bmcclure



Joined: 24 Nov 2007
Posts: 774

PostPosted: Mon Jun 01, 2009 8:19 pm    Post subject: Reply with quote

Sorry, I noticed that too; I must have misread the error message from AHK.

Yes, I was referring to the parameters. More often than not I'll be passing variables to Class_invoke for its parameters, but it would be nice not to have to.

You bring up a good point, though--it would also be expected to work when passing a byref, so changing it might not be the best option either.

I can't think of any graceful way to get around it; I could just assign the values to variables and use them with Class_invoke how it is now, or perhaps a second function could be created without byrefs, maybe Class_sinvoke (for string invoke) or something?

Now that I understand its purpose, it does seem like a good idea to leave the invoke function using ByRefs as you've designed it to do.
_________________
Ben

My Trac projects
My Wiki
[Broken] - My music
Back to top
View user's profile Send private message
animeaime



Joined: 04 Nov 2008
Posts: 1045

PostPosted: Mon Jun 01, 2009 8:38 pm    Post subject: Reply with quote

Well Class_Sinvoke is taken - (Static) invoke. However, as a programmer, I would call the version you are talking about ByValue, whereas the current method is ByRef. So, maybe Class_Vinvoke (for byValue) and Class_SVinvoke for the static version would be good names. However, might I make a suggestion. You can store the values in a temporary variable and pass it.

Example
Code:
Class_invoke(Object, Function, arg1 := "Parameter 1", arg2 := 0xC001D06)



If this solution isn't satisfactory, I can add the forementioned Class_Vinvoke and Class_SVinvoke functions. However, if any parameters need to be ByRef, Class_invoke / Class_Sinvoke would be the one you would need to call; you could use the above solution for the parameters that are values.
_________________
As always, if you have any further questions, don't hesitate to ask.

Add OOP to your scripts via the Class Library. Check out my scripts.
Back to top
View user's profile Send private message Send e-mail
bmcclure



Joined: 24 Nov 2007
Posts: 774

PostPosted: Mon Jun 01, 2009 9:02 pm    Post subject: Reply with quote

I think you're right, turning them into variables for the function call will probably be the easiest way to go, and will avoid the need to create additional functionality for Class.

It would be great if Class could automagically determine if a parameter should be a byref and pass it accordingly, but I don't think it's possible currently.
_________________
Ben

My Trac projects
My Wiki
[Broken] - My music
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Ask for Help All times are GMT
Goto page Previous  1, 2, 3, 4, 5, 6, 7  Next
Page 4 of 7

 
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