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 

OOP or how to create the equivalent
Goto page 1, 2  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
RaptoR



Joined: 27 Jun 2007
Posts: 22
Location: Earth, Cambrian period

PostPosted: Sun Jan 27, 2008 10:34 am    Post subject: OOP or how to create the equivalent Reply with quote

Hi all!

I am trying to convert the following program in Java into AHK, but get stuck in finding more or less acceptable equivalent Sad Here is java code:
Code:

///
public class MyCollection
{
   public static final int MAXL = 20;
   public static final int MAXS = 10;

   Loc[] locs = new Loc[MAXL];
   int size = 0;

   public void add(int x, int y, int n)
   {
      size = Math.min(size + 1, MAXL);
      for (int i = size - 1; --i > 0; )
         locs[i] = locs[i - 1];
      locs[0] = new Loc(x, y);
      locs[0].set(n);
   }
   
   // more methods go here but it doesn't matter now
}

///
class Loc
{
   // set
   boolean [] groups = new boolean[MyCollection.MAXS];
   int x, y;

   public Loc(int x, int y) { this.x = x; this.y = y; }

   public void set(int n) { groups[n] = true; }
   public void unset(int n) { groups[n] = false; }
   public boolean get(int n) { return groups[n]; }
   public Pair getXY() { return new Pair(x, y); }
}

///
class Pair
{
   public int a, b;
   Pair(int a, int b)   { this.a = a; this.b = b; }
}


To simulate an object, I can use ByRef parameter. And in simple cases it is direct equivalent.

To simulate a method for, say, Loc class, I can create functions like these:
Code:

Loc__new_(x, y) { ... return ... } ;; constructor
Loc_set(ByRef this, n) { ... }
Loc_unset(ByRef this, n) { ... }
Loc_get(ByRef this, n) { ... return ... }
Loc_getXY(ByRef this) { ... return ... }

But! What to do with the functions' bodies?

The stumbling block is java "dot notation", i.e. if we have an object (=reference) x, then we can use things like x.method or x.field. What I need in AHK is get access to variable or function from a reference:
Code:

Loc_getXY(ByRef this)
{
    x = this.x
    y = this.y
    return Pair__new_(x, y)
}


How to achieve this?

Thanks in advance.
Back to top
View user's profile Send private message
Guest






PostPosted: Sun Jan 27, 2008 12:01 pm    Post subject: Reply with quote

I would forget the java code style and write it in AHK syntax style.
Back to top
Lexikos



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

PostPosted: Mon Jan 28, 2008 5:04 am    Post subject: Reply with quote

http://www.autohotkey.com/forum/viewtopic.php?p=172832#172832
I wrote:
There are a number of ways to "emulate" object-oriented programming.
...
RaptoR wrote:
What I need in AHK is get access to variable or function from a reference:
The answer depends on how the data is stored. If the objects have a static number of numeric fields, VarSetCapacity and NumPut/NumGet would probably be most efficient. If the objects have arrays or string fields, Scripting.Dictionary would be easier. Have a look at the above link, then decide whether you need wrapper functions. Smile
Quote:
I would forget the java code style and write it in AHK syntax style.
If feasible, I'd also lean towards abandoning OOP concepts.
Back to top
View user's profile Send private message
RaptoR



Joined: 27 Jun 2007
Posts: 22
Location: Earth, Cambrian period

PostPosted: Mon Jan 28, 2008 11:36 am    Post subject: Reply with quote

lexikos wrote:
The answer depends on how the data is stored. If the objects have a static number of numeric fields, VarSetCapacity and NumPut/NumGet would probably be most efficient. If the objects have arrays or string fields, Scripting.Dictionary would be easier. Have a look at the above link, then decide whether you need wrapper functions. Smile


Thank you for the answer!

I rethought the question and realized, that I need some sort of "packing" and "unpacking". "Packing" is gathering things together and assigning a name. "Unpacking" is taking the name and get access to the things.

According to your suggestion the first implementation of this concept is record type, in AHK it needs NumPut/NumGet, hardcoding offsets and wrapper functions to ease the usage.

Second implementation is hash map, but it needs special attention to the keys to avoid name clash. Or use several hash maps - one map per namespace.

Third implementation come into my head is combine names like arrays in AHK.
Code:

size := "_size"

value1 := "my_value_goes_here"
value1_size := 123444

value2 := "your_value_goes_here"
value2_size := 666342

function("value1")
function("value2")

function(var)
{
   global size
   Log("var = " %var%)
   Log("var_size = " %var%%size%)
}

Obvious disadvantage is only one namespace - global.

Fourth implementation could be encode everything in the long string and parse it when one needs to use it. I doubt it could be made efficiently Smile

Probably there are more ways to implement packing and unpacking. But for the problem at hand the most preferrable way is the first one. You rule! Cool

Quote:
If feasible, I'd also lean towards abandoning OOP concepts.

You mean there is something more powerful? (lets take no Haskell, Lisp etc, something for human programmers Very Happy)
Back to top
View user's profile Send private message
RaptoR



Joined: 27 Jun 2007
Posts: 22
Location: Earth, Cambrian period

PostPosted: Mon Jan 28, 2008 11:38 am    Post subject: Reply with quote

Anonymous wrote:
I would forget the java code style and write it in AHK syntax style.

Could you please show me, what AHK syntax style is? IMHO, concepts are independent of the language.
Back to top
View user's profile Send private message
Lexikos



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

PostPosted: Mon Jan 28, 2008 10:33 pm    Post subject: Reply with quote

Perhaps Guest meant procedural code vs. objects in general, or maybe using AutoHotkey pseudo-arrays.
Back to top
View user's profile Send private message
Tuncay



Joined: 07 Nov 2006
Posts: 384
Location: Berlin

PostPosted: Mon Jan 28, 2008 11:02 pm    Post subject: Reply with quote

RaptoR
Sometimes on big scripts, I would have a way to program in AutoHotkey using OOP. In real programming languages, this is a real advantage. But in an simple scripting language, OOP is overkilling most non programmers.

The AHK language does not support explicitly OOP or any feature of. So we have to emulate it somehow. But this would never be save. But emulating some aspects would impact the performance much and make things complicated.
Back to top
View user's profile Send private message Send e-mail
Guest






PostPosted: Tue Jan 29, 2008 12:58 am    Post subject: Reply with quote

Tuncay wrote:

Sometimes on big scripts, I would have a way to program in AutoHotkey using OOP. In real programming languages, this is a real advantage. But in an simple scripting language, OOP is overkilling most non programmers.

The AHK language does not support explicitly OOP or any feature of. So we have to emulate it somehow. But this would never be save. But emulating some aspects would impact the performance much and make things complicated.


omg that really changed my perspective.

Danke Rolling Eyes
Back to top
Tuncay



Joined: 07 Nov 2006
Posts: 384
Location: Berlin

PostPosted: Wed Jan 30, 2008 7:17 pm    Post subject: Reply with quote

Guest wrote:
omg that really changed my perspective.

Are you RaptoR?? If you mean this in an ironical way ... so I donīt know why.
Back to top
View user's profile Send private message Send e-mail
RaptoR



Joined: 27 Jun 2007
Posts: 22
Location: Earth, Cambrian period

PostPosted: Thu Jan 31, 2008 11:01 am    Post subject: Reply with quote

Tuncay wrote:

Are you RaptoR?? If you mean this in an ironical way ... so I donīt know why.


Noooo! Guest is not me, dont be confused so easy! Smile
Back to top
View user's profile Send private message
RaptoR



Joined: 27 Jun 2007
Posts: 22
Location: Earth, Cambrian period

PostPosted: Thu Jan 31, 2008 12:07 pm    Post subject: Reply with quote

lexikos wrote:
Perhaps Guest meant procedural code vs. objects in general, or maybe using AutoHotkey pseudo-arrays.


I did a little step towards emulating OOP, although met with several obstacles.

First, it is not possible to use ByRef parameters because we sometimes have to return an object, like in the java code below:
Code:

   public Pair getXY() { return new Pair(x, y); }

I don't know how to write it using Byrefs, so I had to use integer numbers as object references.

Second. Lets consider the "constructor":
Code:

Bug_new(x) ; constructor
{
   global MAXS
   VarSetCapacity(this, (MAXS + 1) * 4, 0)
   NumPut(x, this)
   return &this
}

Here returned this is just number numerically equal to pointer to the buffer. But for some reason the buffer is shared among different calls!:
Code:

bug1 := Bug_new(666)
bug2 := Bug_new(777)
Log(bug1 ", " bug2) ; ouptuts "4160032, 4160032" :-(

That's why I use now inner static object counter:
Code:

Bug_new(x) ; constructor
{
   global MAXS
   static obj := 0
   obj++
   VarSetCapacity(this%obj%, (MAXS + 1) * 4, 0)
   NumPut(x, this%obj%)
   return &this%obj%
}

And I find it sort of cumbersome. But it is not the main thing.

The main thing is the third one: somehow objecs get corrupted between calls. I better put the all the code here:
Code:

Log("the script is loaded")
MAXS := 5
MAXL := 10

bug1 := Bug_new(666)
bug2 := Bug_new(777)
Log(bug1 ", " bug2)
;; here the objects get corrupted !!
Log(Bug_to_string(bug1))
Log(Bug_to_string(bug2))


Bug_new(x) ; constructor
{
   global MAXS
   static obj := 0
   obj ++

   VarSetCapacity(this%obj%, (MAXS + 1) * 4, 0)
   this := &this%obj%
   NumPut(x, this+0)

   ;; debug output in constructor
   Log(Bug_to_string(this))

   return this
}

Bug_to_string(this)
{
    global MAXS
   str := "{"
   loop % MAXS + 1
   {
      if (a_index == 1)
         str .= NumGet(this+0, (a_index-1) * 4)
      else
         str .= "," . NumGet(this+0, (a_index-1) * 4)
   }
   str .= "}"
   return str
}

it outputs this:
Code:

[04:44:55] the script is loaded
[04:44:55] {666,0,0,0,0,0}
[04:44:55] {777,0,0,0,0,0}
[04:44:55] 4161676, 4161832
[04:44:55] {512,0,0,0,0,0}
[04:44:55] {768,0,0,0,0,0}

I tend to the conclusion, that the corresponding local objects this1 and this2 are disposed after leaving constructor body. If I am right, then these objects should be made global, and the fact is very confusing - encapsulation and "packing-unpacking" concept is gone Sad

Could you clarify when and where objects are allocated and disposed (or garbagecollected) in AHK and where can I read about that?
Back to top
View user's profile Send private message
Lexikos



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

PostPosted: Thu Jan 31, 2008 1:00 pm    Post subject: Reply with quote

RaptoR wrote:
First, it is not possible to use ByRef parameters because we sometimes have to return an object,
Simple use
Code:
getXY(xy)
instead of
Code:
xy := getXY()
This also solves the constructor issue:
Code:
Bug_new(ByRef this, x)
{
    global MAXS
    VarSetCapacity(this, (MAXS + 1) * 4, 0)
    NumPut(x, this)
}

Quote:
Here returned this is just number numerically equal to pointer to the buffer. But for some reason the buffer is shared among different calls!
...
somehow objecs get corrupted between calls.
Local variables are never deleted. If beyond a certain size threshold, the contents of a local variable are freed when the function returns. If below the threshold, the variable is made blank and its memory is reused by the next call. Generally "made blank" means the first byte and the variable's internal length are both set to 0.

This isn't documented, so the only safe assumption is that the memory of a local variable is only "valid" for the duration of the function call. Once the function returns, it is not safe to access.
Quote:
That's why I use now inner static object counter:
...
And I find it sort of cumbersome.
Take a look at the second example in the post I linked to earlier (also below). GlobalAlloc returns a pointer to allocated memory. Pointers can be passed to and from functions, since they are simply numbers. The (second) example demonstrates allocating a structure, setting fields, getting fields, and deallocating/freeing the structure.
http://www.autohotkey.com/forum/viewtopic.php?p=172832#172832
Quote:
Could you clarify when and where objects are allocated and disposed (or garbagecollected) in AHK and where can I read about that?
You can read about it in posts like this one, or AutoHotkey's C++ source code. Smile
Back to top
View user's profile Send private message
RaptoR



Joined: 27 Jun 2007
Posts: 22
Location: Earth, Cambrian period

PostPosted: Thu Jan 31, 2008 2:45 pm    Post subject: Reply with quote

[quote="lexikos"]
RaptoR wrote:
First, it is not possible to use ByRef parameters because we sometimes have to return an object,
Simple use
Code:
getXY(xy)
instead of
Code:
xy := getXY()
This also solves the constructor issue:
Code:
Bug_new(ByRef this, x)
{
    global MAXS
    VarSetCapacity(this, (MAXS + 1) * 4, 0)
    NumPut(x, this)
}


Mmm, no Smile I took this approach but get stuck with converting the following code:
Code:

public void add(int x, int y)
{
   size = Math.min(size + 1, MAXL);
   shiftr(size - 1);
   locs[0] = new Loc(x, y);
}

Analog is
Code:

Set_add2(this, x, y)
{
   size := Set_get_size(this)
   Set_set_size(this, (MAXS < size + 1 ? MAXS : size + 1))
   Set_shiftr(this, size - 1)
   Loc_new(loc, x, y) ;; !!!!!!! loc is local!
   Set_set_locs(this, 0, loc)
}

and I get the same "corrupting problem" again (loc disappears after exiting from the function).
Back to top
View user's profile Send private message
RaptoR



Joined: 27 Jun 2007
Posts: 22
Location: Earth, Cambrian period

PostPosted: Thu Jan 31, 2008 2:47 pm    Post subject: Reply with quote

lexikos wrote:

Take a look at the second example in the post I linked to earlier (also below). GlobalAlloc returns a pointer to allocated memory. Pointers can be passed to and from functions, since they are simply numbers...

I consider GlobalAlloc as the last way to try, because it has obvious disadvantage - need to free memory manually.
Back to top
View user's profile Send private message
grupo
Guest





PostPosted: Thu Jan 31, 2008 10:41 pm    Post subject: Reply with quote

Sorry,it is off topic...
I am the Guest from the first reply.
I must confess that I did not read your post carefully Embarassed because
most(all??) threads I have seem here asking "how to convert this autoit|c++|c#|vb|js...etc code to ahk"
were posted by newbies with zero knowledge, then I adviced to try a basic ahk code.
Back to top
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Ask for Help All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
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