Using functions from lang/core.rb in a ruby class

Sam’s been pretty vocal about not wanting Sonic Pi to head into an object oriented direction. Still, for people who are really familiar with Ruby it feels weird to be locked into the procedural model of the Sonic Pi DSL.

Though it’s not supported, I do this all the time and I’ve developed a pretty elegant way of going about using my own classes as libraries.

You can really shoot yourself in the foot with this approach, especially with threads, so if you don’t know ruby in and out, avert your gaze.

This is how I do it:

# Usually, put this defonce in a file like "/path/to/my/doorbell.rb"
# You must set override to true to make changes

defonce :use_doorbell, :override => false do
  class Doorbell
    def initialize(amp=1.0)
      @amp = amp
    end
    
    def self.set_runtime(rt)
      @@runtime = rt
    end
    
    def runtime
      @@runtime
    end
    
    def ring
      runtime.with_synth :pretty_bell do
        runtime.play 67, amp: @amp
        sleep 0.75
        runtime.play 60, amp: @amp
      end
    end
  end
  
  Doorbell.set_runtime(self)
end

# Usually load the library from the file
# run_file "/path/to/my/doorbell.rb"

use_doorbell

Doorbell.new(0.7).ring
1 Like