Old 07-17-2018, 09:15 PM   #1
InfiniteDimensionality
Human being with feelings
 
Join Date: Jun 2017
Posts: 187
Default defer not calling function

reaper.defer("reaper.ShowConsoleMsg('asdfasdfafd') ;");

Does not display the message on the screen

and I get other defer errors about trying to execute a string

Says trying to execute a string function. Place that same code in the main module and it works fine.

In other cases defer works fine. Can one not run multiple defers in the same script? If so, maybe a proper error would be nice.

All I get is the attempt to call string error without any info where or who or why and all I know is that it is related to defer.
InfiniteDimensionality is offline   Reply With Quote
Old 07-17-2018, 09:32 PM   #2
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

Because you are trying to defer a string - the outer pair of "s mean your ShowConsoleMsg call is just a string, which clearly can't be deferred. Just remove those and it works:
Code:
reaper.defer(reaper.ShowConsoleMsg("asdfasdfafd"))
As is, it will just print your message on the next update loop. If you want the script to keep running, you need a function that will keep deferring itself, like so:
Code:
local function Main()
  reaper.ShowConsoleMsg("asdfasdfafd")
  reaper.defer(Main)
end

Main()
Now, the downside is that this will keep running indefinitely. Depending on what your script is doing, you probably want to include a check for some condition (a script window having been closed, or the user having hit Transport: Stop).
Code:
local function Main()
  if still_want_to_be_running() then
    reaper.ShowConsoleMsg("asdfasdfafd")
    reaper.defer(Main)
  end
end
As for having multiple defers, I assume you mean what I did above. If you mean separate functions all being deferred at the same time... apparently yes:
Code:
local function do_a()
  reaper.ShowConsoleMsg("a")
end
local function do_b()
  reaper.ShowConsoleMsg("b")
end
local function do_c()
  reaper.ShowConsoleMsg("c")
end

reaper.defer(do_a)
reaper.defer(do_b)
reaper.defer(do_c)
Not sure why you'd want to, and in most cases it would be simpler to put all of those calls into a single function and defer that instead. But whatever works for you.

(Incidentally, ;s are only ever required if you want to put more than one statement on a line, i.e. local a = 1; local b = 2; local c = 3)
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 07-17-2018, 10:07 PM   #3
InfiniteDimensionality
Human being with feelings
 
Join Date: Jun 2017
Posts: 187
Default

Quote:
Originally Posted by InfiniteDimensionality View Post
reaper.defer("reaper.ShowConsoleMsg('asdfasdfafd') ;");

Does not display the message on the screen

and I get other defer errors about trying to execute a string

Says trying to execute a string function. Place that same code in the main module and it works fine.

In other cases defer works fine. Can one not run multiple defers in the same script? If so, maybe a proper error would be nice.

All I get is the attempt to call string error without any info where or who or why and all I know is that it is related to defer.
The problem is that you cannot defer a string that takes an argument for some reason and you cannot defer a function that takes at least one argument, even if you want nil passed.

I had to resort to creating a function that called the function and this worked.


essentially

reaper.defer(curry(foo, input))


where curry really just partially applies input, which for one input completely defines foo. Calling this like

reaper.defer("foo(input)");
or
reaper.defer("foo("..input..")");
or
reaper.defer("foo");

all fail.
InfiniteDimensionality is offline   Reply With Quote
Old 07-17-2018, 11:59 PM   #4
cfillion
Human being with feelings
 
cfillion's Avatar
 
Join Date: May 2015
Location: Québec, Canada
Posts: 4,937
Default

Code:
reaper.defer(function() reaper.ShowConsoleMsg("Hello World!\n") end)

Last edited by cfillion; 07-18-2018 at 12:04 AM.
cfillion is offline   Reply With Quote
Old 07-18-2018, 02:35 PM   #5
InfiniteDimensionality
Human being with feelings
 
Join Date: Jun 2017
Posts: 187
Default

Quote:
Originally Posted by cfillion View Post
Code:
reaper.defer(function() reaper.ShowConsoleMsg("Hello World!\n") end)
But again, this doesn't work with calling functions that require a parammeter to be passed

function msg(x) reaper.ShowConsoleMsg(x) end

reaper.defer(msg("test")) error or is not called
reaper.defer('msg("test")') fails also

reaper.defer(apply(msg, "test")) works.

where apply simply returns a new function that wraps the call with the argument.

It seems to be an aberration of reaper since I don't see why it can't handle those cases. The main issue is how they fail and without giving any info where the failure occurs.
InfiniteDimensionality is offline   Reply With Quote
Old 07-18-2018, 03:43 PM   #6
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

It's not Reaper, that's how Lua works.

When you provide the argument and parentheses, you're actually calling the function and giving its returned value to reaper.defer. To defer a function, you have to give it a function.

Wrapping your function and arguments in a function is the correct way to do it - the same applies elsewhere in Lua.

If Cockos wanted, they could possibly modify defer to accept extra arguments and pass those to the called function. That's what the buttons in my GUI do and it works well.
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Old 07-18-2018, 07:56 PM   #7
InfiniteDimensionality
Human being with feelings
 
Join Date: Jun 2017
Posts: 187
Default

Quote:
Originally Posted by Lokasenna View Post
It's not Reaper, that's how Lua works.

When you provide the argument and parentheses, you're actually calling the function and giving its returned value to reaper.defer. To defer a function, you have to give it a function.

Wrapping your function and arguments in a function is the correct way to do it - the same applies elsewhere in Lua.

If Cockos wanted, they could possibly modify defer to accept extra arguments and pass those to the called function. That's what the buttons in my GUI do and it works well.

Yes, but I am not passing a string that represents the function call. I realize in the first instance it calls defer with msg but the point it doesn't work correctly nor provide a proper error message but just craps out, so if one mistakenly does that then it is a difficult bug to fix.

In any case, the work around is easy enough but just that it can be a hard to track bug.
InfiniteDimensionality is offline   Reply With Quote
Old 07-18-2018, 08:15 PM   #8
Lokasenna
Human being with feelings
 
Lokasenna's Avatar
 
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
Default

Your examples where it doesn't work are because you didn't give it a function to defer. Plain and simple.

When you include ()s, you're telling Lua to call the function right then and there. That is:
Code:
reaper.defer(msg("test"))
is the same thing as
Code:
retval = msg("test")
reaper.defer(retval)
msg doesn't return anything, so retval is nil. You're telling defer to call nil as a function, which is what the error message says.

When you include quotes, you're telling Lua that everything in between is a string. That is:
Code:
reaper.defer('msg("test")')
is the same thing as
Code:
str = 'msg("test")'
reaper.defer(str)
str is a string. You're telling defer to call it as a function, which is what the error message says.

The error messages are correct; they're telling you exactly what the problem is.

For comparison, let's look at a working version:
Code:
reaper.defer( function() msg("hello!") end )
is the same thing as
Code:
function wrap()
  msg("hello!")
end

reaper.defer(wrap)
Note that there are no ()s attached to wrap in the defer call, because you don't WANT to call wrap. You want to give defer a function that IT can call later. wrap() is not a function, just like msg("hello!") is not a function - they're whatever the function returns. Consider:
Code:
y = math.floor( math.sin(x) )
We use this sort of structure all the time, because it avoids having to create a temporary variable for the value returned by math.sin(x). defer is behaving the same way.
__________________
I'm no longer using Reaper or working on scripts for it. Sorry. :(
Default 5.0 Nitpicky Edition / GUI library for Lua scripts / Theory Helper / Radial Menu / Donate
Lokasenna is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 02:24 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.