Problem working with external editor

Okay, due to large file size I started working with sublime, which is a fine editor. But I’m running into a weird glitch in my toolchain.
I can’t seem to get sonic pi to consistently reload the external file on subsequent runs. The files just define a bunch of methods/functions, notably the one called “arrange”.
I run the code, see a problem, try to fix it, and run again. But sonic pi doesn’t seem to be running the updated code, even though sublime saved it to the hard drive.
Here’s the code in question:

run_file "C:\\Users\\harry\\Desktop\\Scripting\\SonicPi\\YummyFillings.rb"

run_file "C:\\Users\\Harry\\Desktop\\Scripting\\SonicPi\\arrange_buggy.rb"

kick = :bd_ada
snare = [:sn_dolf, :sn_dub, :sn_generic, :sn_zome]
hat = (ring :hat_bdu, :hat_cab, :hat_cats, :hat_gem, :hat_gnu)
bass = :bass_foundation

test = :ambi_drone

use_bpm 120
##| arrangement = {bass => "q :e3 m7 asc,q,q,q", kick =>"q,q,q,q", snare => "rq,h,q", hat => "qt,et,tq,te,qt,et,qt,et"}
##| arrangement = {bass => "q :e3 m7 rand,q,q,q"}

arrangement = {test => "8w"}
defaults = {test => "cutoff: 70, release: 0.25, sustain: 4"}
envelopes =  { test => "'amp',16" }
lfos = nil
trancegates =  nil
effects = {:ambi_drone => ":flanger depth: 1" }

arrange arrangement, defaults, envelopes, lfos, trancegates

Is there a way to force sonic pi to read it again from the hard drive? It seems to be caching it and not recognizing that the file’s been updated.
My kludge is to close & reopen sonic pi after every edit, which is slow and annoying. Is there (please) a better way?

PS When I run it the first time, it throws an error saying the arrange method is undefined. Then I run it again, and arrange is defined. So something is wonky with the run_file command, but I don’t know what.

Hi, I think you might want to use eval_file.

What’s the difference?

Take a look at the documentation for each function which you can access in the Lang section of the help window:

Evaluate the contents of the file as a new Run
Reads the full contents of the file with path and executes it in a new Run. This works as if the code in the file was in a buffer and Run button was pressed

Evaluate the contents of the file inline in the current thread like a function.
Reads the full contents of the file with path and executes within the current thread like a function call.

The behaviour you’re observing is nothing to do with caching - neither approach caches anything. Instead, you’re observing a race condition in that when you use run_file the contents of the file is executed in a new thread, so two run_files one after another will be running at the same time as the rest of your code. You can observe this behaviour by pressing the Run button a bunch of times quickly and you’ll hear the sounds overlap as you’re triggering multiple runs to execute at the same time.

However, if you want treat the code as if it was inline of the code in the buffer (as if you had cut and pasted it) you want to use eval_file which will not start the code in a new thread and will effectively block the current thread until the code in the file has completed executing. This is necessary if you’re relying on the code in that file to setup state such as function definitions.

If you define a function with code that is executed by run_file you can’t be guaranteed that the function has been defined before you use it. If you use eval_file you can be sure that the function has been set up by the time that eval_file has been completed as it is executed in the same thread.

Concurrency is fun!

Okay, that makes things super clear.
I appreciate you taking time to explain these nuances to a noob.
Think I’ll join your patreon! :slight_smile:

1 Like

@HarryLeBlanc - Thanks so much for your kind and generous support - it means such a lot and without Patreon I’d have been forced to stop working on and maintaining Sonic Pi a long time ago.

Huge hugs!

Thank you for creating and maintaining sonic pi!

1 Like