Page 10 of 25

Re: middleclass & middleclass-extras: OOP for LUA

Posted: Fri Nov 05, 2010 2:35 pm
by Robin
TechnoCat wrote:What is the difference between these two? Other than capitalization?
That kikito's class variable name is different from the instance variable name. I'm simply being consistent with the way method naming works: if an instance has a value for a certain key, it will be used, otherwise the same one in the class, if it isn't there, the one in its superclass, etc.
kikito wrote:Second, it is a "ghost atribute". Think about this:

Code: Select all

for k,v in pairs(pickle) print(k, '=>', v) end
If you explicitly did self.intensity = ... on the initializer, you will get 'intensity' printed out. But it will not be printed out if you just put 'intensity' as a class variable. It could be kind of inconsistent, too: depending on the implementation, some instances would print 'instance' and others wouldn't.
Since when would that matter? It surely doesn't matter for method names, does it?
kikito wrote:The only benefit is that you get rid of one line on the initializer.
That, and less complexity.
kikito wrote:In addition to this, on middleclass there's the assumption that 'methods are in classes, and attributes are in instances'. It's not currently used or enforced (I think) on middleclass-extras, but it might in the future (think serialization). Instances using class variables like that are less future-proof.
Hm. Well, the way I did it would still be future-proof then. :P

Re: middleclass & middleclass-extras: OOP for LUA

Posted: Fri Nov 05, 2010 4:48 pm
by kikito
Robin wrote:Less complexity.
I think removes complexity in some places, but it also increases complexity in others. Instance initialization is (marginally) simplified, but now there's a new item one has to take into account. To me, personally, the second part is more important; As I get older, keeping several things on my head simultaneously is increasingly difficult. That's why I don't like C++ very much and started using LÖVE in the first place.

It also helps drunk programming.
Since when would that matter? It surely doesn't matter for method names, does it?
Oh, but where and how you declare methods matters. Consider this:

Code: Select all

function Person:initializer()
  super.initialize(self)
  self.x = 0
  self.y = 0
  function self:run() -- defining a method inside initialize!
    ...
  end
end
This is adding a method to every instance instead of a method to the class. It can be done, but it isn't something that I would recommend. In addition to making finding method definitions more difficult. It also adds new "circumstances" that one has to think about; for example, if I subclass Person, and want to override run, you can't do it normally:

Code: Select all

Postman = class('PostMan', Person)
function Postman:run()
...
end
postman = Postman:new()
postman:run() --this doesn't call Postman:run()!
It's the same kind of issue, with the exception that right now I have just not needed to use the 'class variable' assumption yet. I can't agree with using class variables that way and can't really recommend it.

Re: middleclass & middleclass-extras: OOP for LUA

Posted: Fri Nov 05, 2010 5:37 pm
by Robin
kikito wrote:Instance initialization is (marginally) simplified, but now there's a new item one has to take into account. To me, personally, the second part is more important; As I get older, keeping several things on my head simultaneously is increasingly difficult. That's why I don't like C++ very much and started using LÖVE in the first place.
I was actually talking about having to keep less things in your head:

Code: Select all

First way:
         | Unoverwritten | Overwitten    |
------------------------------------------
CLASS    | DEFAULT_VAR.. | DEFAULT_VAR.. |
INSTANCE |               | variable      |
# vars   |             1 |             2 |

Second way:
         | Unoverwritten | Overwitten    |
------------------------------------------
CLASS    | variable      |               |
INSTANCE |               | variable      |
# vars   |             1 |             1 |
kikito wrote:It also helps drunk programming.
:rofl: How exactly?
kikito wrote:It's the same kind of issue, with the exception that right now I have just not needed to use the 'class variable' assumption yet. I can't agree with using class variables that way and can't really recommend it.
Which is exactly my point.

EDIT: let's stop this discussion, we're just talking about preferences now, and different people can prefer different things without the world falling apart.

Re: middleclass & middleclass-extras: OOP for LUA

Posted: Fri Nov 05, 2010 10:48 pm
by TechnoCat
Sorry to continue it contrary to robin's request, but I'm at such a loss still. Could I see a side-by-side comparison of the two techniques with a pros and cons?

Re: middleclass & middleclass-extras: OOP for LUA

Posted: Sat Nov 06, 2010 9:26 am
by Robin
I can't speak for kikito, but I'd say that'd be rather hard, since the pros and cons are so subjective in nature.

EDIT: what I'm saying is, just pick one and stick with it. ;)

Re: middleclass & middleclass-extras: OOP for LUA

Posted: Sat Nov 06, 2010 11:15 am
by kikito
I'm happy enough that anybody uses my lib :)

Why don't you paste the code you want to use? I can give you my opinion about it, and robin too.

Re: middleclass & middleclass-extras: OOP for LUA

Posted: Sun Nov 07, 2010 6:13 pm
by TechnoCat
kikito wrote:Why don't you paste the code you want to use? I can give you my opinion about it, and robin too.

Code: Select all

MessageBox = class('MessageBox')
MessageBox.text = "Default"
function MessageBox:initialize()

end

TimedBox = class('TimedBox')
TimedBox:subclass('MessageBox')
function TimedBox:initialize()
  super.initialize(self)
end

StayBox = class('StayBox')
StayBox:subclass('MessageBox')
function StayBox:initialize()
  super.initialize(self)
end

ChoiceBox = class('ChoiceBox')
ChoiceBox:subclass('MessageBox')
function ChoiceBox:initialize()
  super.initialize(self)
end

Code: Select all

function love.load()
  msg = MessageBox:new()
  print(msg.text)
  timed = TimedBox:new()
  print(timed.text)
  timed.text = "Not Default"
  print(timed.text)
  msg.text = "Different Default"
  stay = StayBox:new()
  print(stay.text)
  print(timed.text)
end
Result:

Code: Select all

Default
nil
Not Default
nil
Not Default
Expected:

Code: Select all

Default
Default
Not Default
Different Default
Not Default

Re: middleclass & middleclass-extras: OOP for LUA

Posted: Sun Nov 07, 2010 6:30 pm
by Robin
Hm, I wouldn't know what's going on here, but shouldn't

Code: Select all

  msg.text = "Different Default"
be

Code: Select all

  MessageBox.text = "Different Default"
?
Since the former set an instance variable, not the class variable.

Re: middleclass & middleclass-extras: OOP for LUA

Posted: Sun Nov 07, 2010 6:42 pm
by TechnoCat
Robin wrote:Since the former set an instance variable, not the class variable.
Oh, yeah. That hit the nail on the head. Thanks Robin.

But shouldn't timed.test also be Default off the bat?

Re: middleclass & middleclass-extras: OOP for LUA

Posted: Sun Nov 07, 2010 6:44 pm
by Robin
TechnoCat wrote:But shouldn't timed.test also be Default off the bat?
That's what I'd think.

Deep middleclass magic?