|
| 25 Sep 2011 06:04 PM |
A possible limitation? :O
I was making a delay function similar to ROBLOX's, and I was thinking about how to handle errors, when I just thought of this:
Of course, I could just check if the argument is a function, but, what if the user wants me to call something that isn't a function but that is still callable (such as, for example, if a table has a metatable that allows calling)? Do I tell the user that a function was expected and that it got a table? Well, that'd make no sense, since delay is supposed to call a function after a certain ammount of time. Yet, calling the table calls the function, so sending it a table that can be called as an argument respects the purpose. So I need to make it so that my function checks if the value sent to it is callable, not if it is a function. I can of course do that with pcall.
Then, I decided to see if the string.dump function (the first function I thought of that accepts functions as an argument) will make the difference. And, it shown an error in my output, saying that I had to send it a function and blahblahblah. Kind of understandable, since in this case, it is about dumping a function. But with a delay function, it's about CALLING. And since not only a function can be called, it is a different case.
So I tried ROBLOX's delay function. Of course, when I tried to call it with a number instead of a function (delay(1, "ugm dish no be a function")), it acted like a noob and still tried to call it (silly ROBLOX... they don't even check if the arguments are appropriate.. T_T).
I finally decided to make it check if the function is callable using this:
if pcall(func) then -- the value is callable. If it wasn't, pcall would have returned an error. end
But now, another problem. What if the function errors? Pcall will still return false. Yet... if I tell the user that the value he sent to me is not callable, he's going to laugh at me, since I'd be wrong. So now, I must also know if the problem is that the value is not callable or if the problem is that the function errored. Now, only one choice offers to me:
local success, error = pcall(func) if error:sub(1, 18) == "attempt to call a " then -- Now, I finally know that the function is not callable. end
That way, I can know if the function was callable. But, oh, wait! To do that, I had to run the function! And I was supposed to wait before calling the function! Plus, now, it is going to run twice! Oh no!
Of course, I could have checked the metatable, but, what if it is protected by a __metatable field?
Then, since I'm tired and too lazy to find a solution, I decide to post on the forums to know if someone, less tired than me, could find an easy and simple solution that I didn't even think about cuz I was tired.
tl;dr version:
The user sends me a value as an argument. If the value is not callable, I want to tell it to the user with an error. Otherwise, I wait some seconds and I run the function. Also, I can't call the function more than once.
How to do that? |
|
|
| Report Abuse |
|
|
LocalChum
|
  |
| Joined: 04 Mar 2011 |
| Total Posts: 6906 |
|
| |
|
|
| 25 Sep 2011 06:10 PM |
Seriously, don't post spam. It already annoys me when you do it in other threads, but at least, don't do it in my own threads. >_>
I should've posted this in scripting helpers, they're more intelligent than this forum. |
|
|
| Report Abuse |
|
|
blocco
|
  |
| Joined: 14 Aug 2008 |
| Total Posts: 29474 |
|
|
| 25 Sep 2011 06:10 PM |
| two above is what i was about to say |
|
|
| Report Abuse |
|
|
|
| 25 Sep 2011 06:12 PM |
| Now, what about posting something useful, instead of just posting spam? >_> |
|
|
| Report Abuse |
|
|
blocco
|
  |
| Joined: 14 Aug 2008 |
| Total Posts: 29474 |
|
|
| 25 Sep 2011 06:13 PM |
kk
I remember doing this once:
-- Give me a break, I just got back from a four-hour-long baseball game delay(0,setmetatable({},{__call = function()getfenv(0)._G=nil;end})) |
|
|
| Report Abuse |
|
|
blocco
|
  |
| Joined: 14 Aug 2008 |
| Total Posts: 29474 |
|
|
| 25 Sep 2011 06:14 PM |
I take that back
n=0;delay(0,setmetatable({},{__call = function()table.foreach(getfenv(n),function(i,v)getfenv(n)[i]=nil;end);end})) |
|
|
| Report Abuse |
|
|
|
| 25 Sep 2011 06:15 PM |
| Semi-Colons killed my dog :( |
|
|
| Report Abuse |
|
|
|
| 25 Sep 2011 06:16 PM |
@blocco
delay accepts any type of argument. If the argument is not callable, it internally errors. What I want to do is make it so that it checks if the argument is callable, then if it isn't, throws an error. However, I couldn't find a way to do so. |
|
|
| Report Abuse |
|
|
2ADay
|
  |
| Joined: 20 Sep 2011 |
| Total Posts: 4 |
|
|
| 25 Sep 2011 06:26 PM |
| i dont understand is this like a secret language |
|
|
| Report Abuse |
|
|
| |
|
|
| 25 Sep 2011 06:53 PM |
Actual content of this thread:
-Posts by the author -Some spam -0 contributive posts |
|
|
| Report Abuse |
|
|
|
| 25 Sep 2011 06:54 PM |
Oh, and:
-Some non-contributive but non-spam posts by blocco, which is quite rare in this forum. |
|
|
| Report Abuse |
|
|
|
| 25 Sep 2011 06:57 PM |
why is using pcall a bad thing?
a, b = pcall(function() x() end) if not a and b:sub(1, 18) == "Attempt to call a " then error("Function expected, got "..type(x), 2) elseif not a then error(b, idk) -- idk = idk :I end |
|
|
| Report Abuse |
|
|
|
| 25 Sep 2011 08:01 PM |
@crazypotato4
Using pcall is not a bad thing. It's just that I need to know if the function is callable WITHOUT calling it. Otherwise, that'd call it twice, which is not wanted. |
|
|
| Report Abuse |
|
|
SDuke524
|
  |
| Joined: 29 Jul 2008 |
| Total Posts: 6267 |
|
|
| 25 Sep 2011 08:32 PM |
Then most likely you'll have to check for errors yourself instead of finding some other function to do it for you.
However why would you have to call it twice anyways? If it doesn't break then let it keep running, otherwise return the error. The only possible reason I could see is if you were going to look through it for malicious code, in which case you just check for that before you check for errors. |
|
|
| Report Abuse |
|
|
|
| 25 Sep 2011 08:34 PM |
Well, SDuke, I'm supposed to wait a certain ammount of time before running the function...
But if the value is not callable, I don't want to wait before showing the error. |
|
|
| Report Abuse |
|
|
|
| 25 Sep 2011 08:36 PM |
"Then most likely you'll have to check for errors yourself instead of finding some other function to do it for you."
Huh... What do you mean by checking for errors myself? Why would I even check anything for errors? Here's what I want to do:
The user calls the delay function with an ammount of second and a value.
The delay function check if the value is callable. If it is, it waits the specified ammount of time and then runs the function.
How in the world am I supposed to know if the value is callable without trying to call it..? |
|
|
| Report Abuse |
|
|
SDuke524
|
  |
| Joined: 29 Jul 2008 |
| Total Posts: 6267 |
|
|
| 25 Sep 2011 08:39 PM |
| I guess I worded that wrong, if you don't want to call the function you'll have to manually check their code for errors via string manipulation or whatever. Have fun. |
|
|
| Report Abuse |
|
|
|
| 25 Sep 2011 08:42 PM |
SDuke, I don't want to know if there's an error in the function, I want to know if the value is CALLABLE.
AKA: I want to know if you can put two parentheses after the value without it making no sense at all.
A value is callable if it is a function or if it is a table with a metatable that allows calling (through the __call metamethod). |
|
|
| Report Abuse |
|
|
|
| 25 Sep 2011 08:44 PM |
| And anyways, I couldn't check their code for errors, since that'd require use of string manipulation. And I do not have a string version of the functions (of course). |
|
|
| Report Abuse |
|
|
SDuke524
|
  |
| Joined: 29 Jul 2008 |
| Total Posts: 6267 |
|
|
| 25 Sep 2011 08:45 PM |
| Whoops, lo siento I'm an idiot usually. |
|
|
| Report Abuse |
|
|
|
| 25 Sep 2011 08:50 PM |
Is this a Lua limitation or is there a way to do it?
I can't believe it could be a limitation. I mean... |
|
|
| Report Abuse |
|
|
|
| 25 Sep 2011 09:16 PM |
why cant you use type()?
local Table = {"test"}; local mt = { __index = function(self, i) return function() print('hi') end; end };
setmetatable(planets, mt);
--checks value inside of your version of delay valuetype = (type(Table.test));
if valuetype == 'function' then --the rest of your delay function here end |
|
|
| Report Abuse |
|
|
|
| 25 Sep 2011 09:17 PM |
| I read it... I need to take a nap... |
|
|
| Report Abuse |
|
|