Sample name stored in a variable


#1

Hi there,

A question of syntax :

sample_loop_01 = "loop_amen"
sample_loop_02 = "loop_garzul"

define :play_sample do | number |
  
  sampleToPlay = "sample_loop_" + number.to_s
  sample sampleToPlay.to_s
end

play_sample("01")

and of course it gives this as a result

=> Starting run 82

=> Redefining fn :play_sample

{run: 82, time: 0.0}
 ├─ 1.5715419501133787
 └─ sample ["sample_loop_01"]
             - no match found, skipping.

Sure you will know how to resolve this !
cheers


#2

The problem is that the sample function looks for a sample called “sample_loop_01”, not the string inside the variable.
As a fix I would suggest a different indexing system:

samples = ["loop_amen","loop_garzul"]
    define :play_sample do | number |
      sample samples[number]
      puts samples
    end
    play_sample(0)

#3

Hello,
Yes it’s a way to achieve the goal.

I wish there is a system, as in php, called “dynamics variables”

<?php
$var = 'hello';
$hello = 'Coucou';
echo ${$var};
?>

and the outpur is “coucou”

not available in ruby ?


#4

There is a function to run code from a string: run_code “”
I don’t know if it works with just a variable name, but it should.


#5

What about using a hash?

sl = {"sample_loop_01" => :loop_amen,"sample_loop_02" => :loop_garzul}

define :play_sample do | number |
  
  sampleToPlay = "sample_loop_" + number.to_s
  x= sampleToPlay.to_s
  sample sl[x]
end

play_sample("01")

Essentially it carries out the substitution that you want.


#6

@nlb - beyond your original code snippet here - I’m interested in how/why you are wanting to use dynamic variables (I assume in the context of a larger program). There is certainly such a thing in plain ruby, (ie, not part of the supported Sonic Pi syntax), though it is a little more verbose than PHP. See https://www.rosettacode.org/wiki/Dynamic_variable_names#Ruby for example.
Though having said that, I wonder if there is a way to achieve what you want without needing them… maybe if you elaborate on your use case here you might find that there’s an even simpler solution!


#7

thanks for your answer.
Well the best solution is the array solution the simpler or the hash the more easy in my case.
and there are solutions i can understand easily :slight_smile:
So the question about the dynamic variables is topic off because useless to achieve what i want to do.

But, not to die silly, i try this code

x = "foo"
instance_variable_set x, 42
p "The value of #{x} is #{instance_variable_get x}"

and it fails. Can we write any kind of ruby code in sonic Pi interface ?

I give you some feedback of my small project as soon as possible.
cheers


Get with the name of a variable
#8

Sonic Pi makes available a ‘domain specific language’ that is built on top of Ruby, so not all plain Ruby code is supported, no. Some parts, like basic math operations, are more than likely going to work; more complicated things like using classes, gems, meta-programming, etc may work, but are definitely not guaranteed. You can try whatever in Ruby, but anything other than the commands specific to Sonic Pi are not officially supported.

As far as your most recent snippet above, there are several changes that would be needed to get it to work: firstly, instance variables are represented with an @ at the start of their name, and secondly (here being an example of the ‘not everything in Ruby is supported in Sonic Pi’) puts cannot be shortened to p. So this would work:

x = '@foo'
instance_variable_set x, 42
puts "The value of #{x} is #{instance_variable_get x}"

Looking forward to reading about your project :slight_smile: Keep us posted!


#9

merci !

so set and get examples

x = "@foo"
instance_variable_set x, 42
puts "The value of #{x} is #{instance_variable_get x}"


i=1

4.times do
  controlPushName = "c#{i}"
  puts controlPushName
  set(controlPushName,i*2)
  i = i+1
end


number = 1
4.times do
  controlPushName = "c#{number}"
  puts get(controlPushName)
  number = number +1
end

#10

If you wanted a more direct analog to the PHP dynamic variables, you might try local_variable_get/set

foo = "bar"
puts binding.local_variable_get :foo  # => "bar"
binding.local_variable_set :foo, "qux"
puts foo  # => "qux"

That being said I think in most cases what you really want when you reach for something like that is a hash as @robin.newman said, or an array works too if you only need to index by number.