So, in "re-writing" my code, I have created a local table, RIA, and renamed my functions to "RIA:doesSomething()".
Now, I'm using Portfolio as my Interface Options framework. Very simple, easy, just works for me. Anyway, I've had to refer to my functions as "RIA.doesSomething" for callbacks. Probably the right way, but some explanation regarding this would be helpful for my understanding :)
Yes, I do understand this. However, I think my implementation may be off.
If you could look back into the code, my intent was to put all of my data (more importantly, my functions) into a local table so they did not pollute the global namespace. The problem is that this is producing additional errors when references callback functions in my Options, etc.
Have I implemented this correctly? If so, then I can tell it's more specific errors to fix.
This is a "back-end" file, so changes won't be made here, however feel free to view it as reference to what is going on. When the error mentions this, it's like mentioning that Blizzard's code is wrong.
When the error mentions this, it's like mentioning that Blizzard's code is wrong.
No, it's like mentioning that your code is calling Blizzard API functions wrong, because that's exactly what it is mentioning. :p
Anyway, that is quite possibly the most unnecessarily convoluted method of creating a slider widget I've ever seen, but my best guess would be that you're getting that error because your custom GetValue function isn't returning anything when called on line 154 of Portfolio/Control.lua, so you're passing a nil value to the slider's real SetValue function.
Anyway, I'm unaware of a "GetValue" function that I have. Could you clarify?
As an aside, what do you recommend as a a Blizz Options framework? I'd like something similarly simple to implement. This method is currently working fine, although it is discontinued and somewhat bloated, as I understand.
Even if the error actually happens in Slider.lua, line 103, it's probably because the code tries to pass a nil value to :SetValue. So where does that value comes from ?
Moving up in the stack frame, we see that this value is returned by self:GetValue() at line 154 of Control.lua.
function Portfolio.Control.Update(self)
self:SetValue(self:GetValue(), false, true)
end
So, for some reason you have to find if you want to fix the error, this self:GetValue() returns nil.
I'm not sure if I was misreading that other thread or what, but what I took away from the post that said your functions were polluting the global namespace was that you just needed to put the word "local" in their declarations. I'm not sure it was entirely necessary to attach them all to a table unless you wanted to pass that table around to other parts of your addon. I might be missing something, though...
Though, as a result of looking at the code, I have a question: if a method is declared as...
function Table:Method()
...but is called like...
Table.Method()
...what does that mean for the self parameter? Is that actually just hidden from the parameter list or is that variable and its value injected into the function's scope from the C side? If it's the former, not passing it just means it's empty, right? So, what if there are other parameters.
For example, this...
function RIA:OnEvent(event, ...)
...being used like this...
RIA.eventFrame:SetScript("OnEvent", RIA.OnEvent)
Wouldn't OnEvent be expecting, when called using dot notation, the first parameter to be self? So, wouldn't the event name actually get thrown into self?
Though, as a result of looking at the code, I have a question: if a method is declared as...
function Table:Method()
...but is called like...
Table.Method()
...what does that mean for the self parameter?
It means that inside the function, self will be nil. This is probably a bug in the calling code, unless self isn't used at all in that function, in which case it doesn't matter.
There's no special correspondence between "declaration" and "call" syntax in Lua. (Functions aren't really "declared" as in imperative languages, there's no function signature here.) You can mix and match colon and non-colon styles when defining and calling functions, as long as the parameters match up.
So, what if there are other parameters.
For example, this...
function RIA:OnEvent(event, ...)
...being used like this...
RIA.eventFrame:SetScript("OnEvent", RIA.OnEvent)
Wouldn't OnEvent be expecting, when called using dot notation, the first parameter to be self?
Yes, but "self" as a magic keyword is going to change, obviously. Using colon notation when defining a function just means "there will be a hidden first parameter, and it will be called 'self'". It doesn't bind it to the containing table.
So, wouldn't the event name actually get thrown into self?
It depends on how OnEvent is called. In this case, it's by Blizzard, and their event handlers always take a frame reference as the first parameter, specifically to support colon notation. In the code here, a reference to 'eventFrame' will be passed as the first argument, and will be accessible as "self" inside
function RIA:OnEvent(event, ...)
This is why a lot of event handlers get declared as
local my_event_handler (frame, event, ...) stuff end
with embedded local references to the data structures, so that there's zero possible confusion or misreading about "self".
There's no special correspondence between "declaration" and "call" syntax in Lua. (Functions aren't really "declared" as in imperative languages, there's no function signature here.)
Using colon notation when defining a function just means "there will be a hidden first parameter, and it will be called 'self'".
Two things:
function(param1, param2)
--body
end
That's a function declaration, isn't it? It's defining the parameter list. I can call it with no parameters [as ___()] and it just passes nil for each one, but I can't call it with more parameters than what it was originally "declared" as having and expect those extra values to be accessible. I'd have to put the vararg in there explicitly to be able to use it within the function scope (to make it a "vararg function", I think the error message says).
Your use of the phrasing "there will be" also seems to imply that something is "set" when code like the above is written.
So, given this...
local f = {}
function f.Dot(name)
print(type(name))
end
function f:Colon()
print(self == nil)
end
f:Dot("Johnny") -- this prints "table"
f.Colon() -- this prints "true"
...there is something "saved" at the point of declaration. The self keyword isn't something that magically becomes available within the function's scope. It's really there in the parameter list at the first position. The value "Johnny" disappears into the ether in the first call as there are no more parameters left.
Without having read the thread thoroughly; 'self' is only "magical" in a function definition defined using colon syntax. It is there defined without having been typed out by the programmer, and it's only magical in being defined automatically. Beyond that it's just a normal parameter. Furthermore, both f.Dot and f:Colon are for all intents and purposes regular functions. The fact that they are on a table does not change the behaviour of the functions at all; only that you can call such a function using the colon syntax.
These are essentially the same:
function onEvent(frame, event, ...)
end
aFrame:SetScript("OnEvent", onEvent)
function aTable:OnEvent(event, ...)
end
aFrame:SetScript("OnEvent", aTable.OnEvent)
local f = {}
function f.Dot(name)
print(type(name))
end
function f:Colon()
print(self == nil)
end
f:Dot("Johnny") -- this prints "table"
f.Colon() -- this prints "true"
Is strictly complied as this by Lua :
local f = {}
f.Dot = function(name)
print(type(name))
end
f.Colon = function(self)
print(self == nil)
end
f.Dot(f, "Johnny") -- this prints "table"
f.Colon() -- this prints "true"
foo:bar(...) is just a syntactic sugar for foo.bar(foo, ...).
I mean "declaration" as in a language like C++, Java, etc. Lua doesn't have function prototypes or signatures.
The magic insertion of 'self' happens only when parsing a function being defined with the colon syntax. That's it. That's all. There's nothing else going on.
I haven't looked at the code you've posted, but I don't see what the confusion is here.
The confusion was only related to you telling me that there wasn't anything going on when a function was written down for the first time.
I think it's clear now that if a function is not either defined on a table with colon syntax or manually defined with its first parameter reserved for a frame, it cannot later be called that way.
The confusion was only related to you telling me that there wasn't anything going on when a function was written down for the first time.
....?
I think it's clear now that if a function is not either defined on a table with colon syntax or manually defined with its first parameter reserved for a frame, it cannot later be called that way.
I think it's clear now that if a function is not either defined on a table with colon syntax or manually defined with its first parameter reserved for a frame, it cannot later be called that way.
If you mean this won't work:
function MyAddon.DoStuff()
self:Show()
end
MyAddon:DoStuff()
Then, yes, that is correct, but it has nothing to do with the first parameter being a frame reference; the same applies to any function definition. For example:
local function PrintSomething()
print("MyAddon:", message)
end
PrintSomething("Hello world!")
If you want to pass values to a function, you need to assign those values to named variables in the function definition itself:
local function PrintSomething([b][i]message[/i][/b])
It's no different for functions that will be called via method notation (colon) except that Lua automatically assignes the parent table (note that frames are just tables; the attached userdata that makes them frames has no relevance when it comes to using dot vs colon notation) to a variable named "self".
What are some recommendations for my Slider situation (which is just 1 of the 6 units having trouble)? It appears the callbacks are fine with data... something is complaining with my for loop indexing, whether it be the callback functions themselves, or other functions used by the callback functions referenced.
Now, I'm using Portfolio as my Interface Options framework. Very simple, easy, just works for me. Anyway, I've had to refer to my functions as "RIA.doesSomething" for callbacks. Probably the right way, but some explanation regarding this would be helpful for my understanding :)
In addition, I'm getting this error: http://pastebin.com/wJammv8H
I have a feeling it is in regards to my new function namespace setup.
Here is current code: https://github.com/cralor/rune-it-all/blob/master/RuneItAll.lua
Options: https://github.com/cralor/rune-it-all/blob/master/Options.lua
All the other code can be viewed on GitHub too.
Thanks for the help!
ie,
frame:SetValue(65)
is the same as
frame.SetValue(self, 65)
If using dot notation, you need to pass the reference to the frame as the first parameter of the function.
More specifically, it's the same as frame.SetValue(frame,65) with the usual caveat about only evaluating the "frame" expression once, etc, etc.
If you could look back into the code, my intent was to put all of my data (more importantly, my functions) into a local table so they did not pollute the global namespace. The problem is that this is producing additional errors when references callback functions in my Options, etc.
Have I implemented this correctly? If so, then I can tell it's more specific errors to fix.
All of the files are on the GitHub.
This is a "back-end" file, so changes won't be made here, however feel free to view it as reference to what is going on. When the error mentions this, it's like mentioning that Blizzard's code is wrong.
No, it's like mentioning that your code is calling Blizzard API functions wrong, because that's exactly what it is mentioning. :p
Anyway, that is quite possibly the most unnecessarily convoluted method of creating a slider widget I've ever seen, but my best guess would be that you're getting that error because your custom GetValue function isn't returning anything when called on line 154 of Portfolio/Control.lua, so you're passing a nil value to the slider's real SetValue function.
Anyway, I'm unaware of a "GetValue" function that I have. Could you clarify?
As an aside, what do you recommend as a a Blizz Options framework? I'd like something similarly simple to implement. This method is currently working fine, although it is discontinued and somewhat bloated, as I understand.
Even if the error actually happens in Slider.lua, line 103, it's probably because the code tries to pass a nil value to :SetValue. So where does that value comes from ?
Moving up in the stack frame, we see that this value is returned by self:GetValue() at line 154 of Control.lua.
So, for some reason you have to find if you want to fix the error, this self:GetValue() returns nil.
Though, as a result of looking at the code, I have a question: if a method is declared as...
...but is called like...
...what does that mean for the self parameter? Is that actually just hidden from the parameter list or is that variable and its value injected into the function's scope from the C side? If it's the former, not passing it just means it's empty, right? So, what if there are other parameters.
For example, this...
...being used like this...
Wouldn't OnEvent be expecting, when called using dot notation, the first parameter to be self? So, wouldn't the event name actually get thrown into self?
It means that inside the function, self will be nil. This is probably a bug in the calling code, unless self isn't used at all in that function, in which case it doesn't matter.
There's no special correspondence between "declaration" and "call" syntax in Lua. (Functions aren't really "declared" as in imperative languages, there's no function signature here.) You can mix and match colon and non-colon styles when defining and calling functions, as long as the parameters match up.
Yes, but "self" as a magic keyword is going to change, obviously. Using colon notation when defining a function just means "there will be a hidden first parameter, and it will be called 'self'". It doesn't bind it to the containing table.
It depends on how OnEvent is called. In this case, it's by Blizzard, and their event handlers always take a frame reference as the first parameter, specifically to support colon notation. In the code here, a reference to 'eventFrame' will be passed as the first argument, and will be accessible as "self" inside
This is why a lot of event handlers get declared as
with embedded local references to the data structures, so that there's zero possible confusion or misreading about "self".
Two things:
So, given this...
...there is something "saved" at the point of declaration. The self keyword isn't something that magically becomes available within the function's scope. It's really there in the parameter list at the first position. The value "Johnny" disappears into the ether in the first call as there are no more parameters left.
These are essentially the same:
Is strictly complied as this by Lua :
foo:bar(...) is just a syntactic sugar for foo.bar(foo, ...).
Alright, I've updated my files once again, this time the Options uses the colon to ensure 'self' is passed through.
In my main, I've renamed all mentions of the "RIA" table with "self". Table entries referenced with "self." and functions referenced with "self:".
However, I still have this Slider error. Attached is some additional intel regarding the callbacks. Thanks all.
I mean "declaration" as in a language like C++, Java, etc. Lua doesn't have function prototypes or signatures.
The magic insertion of 'self' happens only when parsing a function being defined with the colon syntax. That's it. That's all. There's nothing else going on.
I haven't looked at the code you've posted, but I don't see what the confusion is here.
I think it's clear now that if a function is not either defined on a table with colon syntax or manually defined with its first parameter reserved for a frame, it cannot later be called that way.
....?
*blink*
Yes, you need to give names to parameters.
If you mean this won't work:
Then, yes, that is correct, but it has nothing to do with the first parameter being a frame reference; the same applies to any function definition. For example:
If you want to pass values to a function, you need to assign those values to named variables in the function definition itself:
It's no different for functions that will be called via method notation (colon) except that Lua automatically assignes the parent table (note that frames are just tables; the attached userdata that makes them frames has no relevance when it comes to using dot vs colon notation) to a variable named "self".
See: http://forums.wowace.com/showpost.php?p=326731&postcount=15
RuneItAll.lua: https://github.com/cralor/rune-it-all/blob/master/RuneItAll.lua
Options.lua: https://github.com/cralor/rune-it-all/blob/master/Options.lua