Quenty
|
  |
| Joined: 03 Sep 2009 |
| Total Posts: 9316 |
|
|
| 26 Apr 2012 08:11 PM |
What is the best way to create classes? I mean, I think I want to use Metatables, right? So on 'Changes' to it, I can terminate certain things, and add other things. Leading to this, if it's destroyed, I think I also want to add weak tables.
So does anyone have a free model, or a way to do this? |
|
|
| Report Abuse |
|
|
stravant
|
  |
 |
| Joined: 22 Oct 2007 |
| Total Posts: 2893 |
|
| |
|
Quenty
|
  |
| Joined: 03 Sep 2009 |
| Total Posts: 9316 |
|
|
| 26 Apr 2012 08:36 PM |
Seems like what I'm looking for. If I was going to use it, I would do...?
local NewObject = class("TheClassName")
And then I'm lost. :/
Can you explain how to use it? How to define and call methods, set properties, and stuff?
It appears that you can do... functions? As the 'ClassName' or something? I'm confused, although, the features from the tests seems good. :D |
|
|
| Report Abuse |
|
|
stravant
|
  |
 |
| Joined: 22 Oct 2007 |
| Total Posts: 2893 |
|
| |
|
Quenty
|
  |
| Joined: 03 Sep 2009 |
| Total Posts: 9316 |
|
|
| 26 Apr 2012 10:18 PM |
That's classy. :D
So, say.... is this correct?
class'ClassNameHere'(function(def) def:Create() self.Property self.Property2 game.ChildAdded:connect(function(child) self.FunctionToCallWhenItHappensWhichAlsoDoublesAsTheEventName:fire(child) end) end
def.event.FunctionToCallWhenItHappensWhichAlsoDoublesAsTheEventName() def.event.EventNumberTwo() end)
CreateClassNameHere().EventNumberTwo:connect(function() print("yay, it fired?") end)
I'm still confused, I don't quite get the syntax..... |
|
|
| Report Abuse |
|
|
stravant
|
  |
 |
| Joined: 22 Oct 2007 |
| Total Posts: 2893 |
|
|
| 26 Apr 2012 10:52 PM |
That's sort of really wrong. Here's the syntax:
class'Adder'(function(def) --inside of this function body you declare all of the methods, --properties, and events
--first, you want the constructor, this is done using a special method "create" --and this create method will be called for every new instance of the class. function def:Create(increment) --do constructor-ey things --You store whatever data you want in "self", and it will be unacessable to --outside code unless you make it public self.Increment = increment end
--now, you want a normal public method, you do this the same way but use --any name other than create function def:Add(arg) self.DidAddNumber:fire(arg) return self.Increment + arg end
--you can make a var public like so: def.getset.Increment() --that will make the var mutable from the outside, you can use "get" or --"getset" for readable or read/writeable public members.
--you can also make custem getters or setters: function def.get:Name() return "Adder for increment: "..self.Increment end
--and getters can get their own variable too! It wont stack overflow function def.get.Increment() return self.Increment end
--Finally, you can add events easily self.event.DidAddNumber() end)
And the usage: local add = CreateAdder(10) add.DidAddNumber:connect(function(num) print("Num "..num.." was added!") end) add:Add(5) print(add.Name) etc... |
|
|
| Report Abuse |
|
|
iNigerian
|
  |
| Joined: 17 Apr 2012 |
| Total Posts: 165 |
|
| |
|
Quenty
|
  |
| Joined: 03 Sep 2009 |
| Total Posts: 9316 |
|
|
| 27 Apr 2012 12:28 AM |
OK. I get the basic concept. However, I am confused on a few things.
-> increment (In the Create method) What is the point?
-> function def.getset.Increment() return 3 end And then...
print(self.Increment) --> 3
So that's a like a property? That can be set, and then, just doing 'get' will get a property that is read only?
And then...
-> self.DidAddNumber:fire(arg) But, no self.event.DidAddNumber(), what happens?
Does it still fire, also can you use the stuff below the 'Create' method IN the create method, like can you set events and stuff in there? I guess private stuff is just variables that you need to save data about?
Wouldn't it generally be good just to keep those public, so they can be read and accessed?
|
|
|
| Report Abuse |
|
|
stravant
|
  |
 |
| Joined: 22 Oct 2007 |
| Total Posts: 2893 |
|
|
| 27 Apr 2012 12:59 AM |
You have to not think of this like the other class systems that I used in the past. The body of the "class" thing is executed immediately, and used to build a class definition. The things like "def.getset.Property1()" are really just a concise way of saying something like "def.AddProperty(canwrite=true, canread=true, name="Property1")".
And when you make an actual instance of the class, only then is Create actually called with a valid self instance. And a lot of work is done for you on that instance.
Same thing with events. The "def.event" proxy just registers that there is that event in the class, and then the system automatically creates the event for you on each instance, so that you can use it. |
|
|
| Report Abuse |
|
|
|
| 27 Apr 2012 02:14 PM |
finally another person who seems to endorse the use of getfenv to fetch calling environment without ugly argument hax.
:D |
|
|
| Report Abuse |
|
|
stravant
|
  |
 |
| Joined: 22 Oct 2007 |
| Total Posts: 2893 |
|
|
| 27 Apr 2012 02:21 PM |
| Are you taking about me? This uses no expensive stuff like that by the way, it's purely done using standard metatable stuff, which makes it reasonably fast. |
|
|
| Report Abuse |
|
|
|
| 27 Apr 2012 02:46 PM |
I can't wait to be able to use it from the RbxUtility library. :/
Mine is better in my opinion, but it is also ridiculously expensive. |
|
|
| Report Abuse |
|
|
|
| 27 Apr 2012 02:58 PM |
@Stravant
You used getfenv to define the variable 'addClass' or whatever into the calling environment.
It's something I do a lot, and sadly, as I guess you know, impossible in 5.2 (Unless you expect them to write class('name', _ENV)) since there's no legacy support for getfenv. :'( |
|
|
| Report Abuse |
|
|
|
| 27 Apr 2012 03:01 PM |
@trappingnoobs
Functions can return values for a reason. |
|
|
| Report Abuse |
|
|
stravant
|
  |
 |
| Joined: 22 Oct 2007 |
| Total Posts: 2893 |
|
|
| 27 Apr 2012 04:23 PM |
"It's something I do a lot, and sadly, as I guess you know, impossible in 5.2 (Unless you expect them to write class('name', _ENV)) since there's no legacy support for getfenv. :'("
When the update happens I'll just change the coding convention to be: local ClassName = class'ClassName'(function(def) ... end)
Not as elegant because you have to repeat the name twice in the general case, but better in the end since you don't force your way into someone else' namespace uninvited. |
|
|
| Report Abuse |
|
|
|
| 27 Apr 2012 04:26 PM |
"Functions can return values for a reason."
Repetetivity or ugliness is criticised for a reason. |
|
|
| Report Abuse |
|
|
|
| 27 Apr 2012 04:27 PM |
Stravant, I'm guessing this is along stretch but since you're, as far as I know, a dev, or at least have a lot of dev input, can't you get them to take the source that defines getfenv in Lua 5.1 and put it into Lua 5.2?
I'm guessing it's not that easy, and if they've completely modified how environments work back-end, not feasible, but if they haven't, and it's feasible, it'd be nice if they put it back in rather than just wiping support for it. |
|
|
| Report Abuse |
|
|
stravant
|
  |
 |
| Joined: 22 Oct 2007 |
| Total Posts: 2893 |
|
|
| 27 Apr 2012 04:33 PM |
"can't you get them to take the source that defines getfenv in Lua 5.1 and put it into Lua 5.2?"
You're right with this statement: "and if they've completely modified how environments work back-end". Environments work fundamentally differently in 5.2, and even I don't think there's any case for having a get/setfenv. Like I said, it may look slightly more elegant but it's generally not a good idea to go inserting things into a calling env. |
|
|
| Report Abuse |
|
|
|
| 27 Apr 2012 04:53 PM |
| stravant got banned?? AWWW SNAP! |
|
|
| Report Abuse |
|
|
|
| 27 Apr 2012 04:55 PM |
| stravant got banned?? AWWW SNAP! |
|
|
| Report Abuse |
|
|
Anaminus
|
  |
 |
| Joined: 29 Nov 2006 |
| Total Posts: 5945 |
|
|
| 27 Apr 2012 05:05 PM |
No one is safe from posting links.
Anyway, now that BindableEvents are around and working, you no longer have to use the signal class. All you have to do is assign the internal value to the BindableEvent, and the external value to BindableEvent.Event. |
|
|
| Report Abuse |
|
|
stravant
|
  |
 |
| Joined: 22 Oct 2007 |
| Total Posts: 2893 |
|
|
| 27 Apr 2012 05:23 PM |
"Anyway, now that BindableEvents are around and working, you no longer have to use the signal class. All you have to do is assign the internal value to the BindableEvent, and the external value to BindableEvent.Event."
I still prefer the signal class. It looks more elegant for stuff that only needs to exist on the Lua-side. The bindable-event could be used to vastly simplify the implementation of the signal class, but I think that there's still an argument for using it on the Lua side.
It would have been nicer if the bindable-event class were identical to normal events (Basically having it as a way to make an RbxScriptSignal instance) rather than having the extra level of indirection "Event" event in it to make it similar to normal Roblox objects. |
|
|
| Report Abuse |
|
|
|
| 27 Apr 2012 07:40 PM |
"I still prefer the signal class. It looks more elegant for stuff that only needs to exist on the Lua-side. The bindable-event could be used to vastly simplify the implementation of the signal class, but I think that there's still an argument for using it on the Lua side."
I prefer BindableEvents. They are handled on C side and, to me, they just feel safer.
"It would have been nicer if the bindable-event class were identical to normal events (Basically having it as a way to make an RbxScriptSignal instance) rather than having the extra level of indirection "Event" event in it to make it similar to normal Roblox objects."
But, then, it couldn't have been an instance like the others.. I think they should just have added a Connect method instead of adding an event, though, in that case, it would have been more complicated to use the same event system...
I think it's better the way they did it, even though it's a less little elegant. |
|
|
| Report Abuse |
|
|