A little list cheatcode

“Lists are immutable. You can’t just pick a single index and overwrite it.”

Me:

define :overwrite do |list, length, position, value|
  
  #empty return list
  outlist = (ring)
  
  #iterate through list
  tick_reset :over
  length.times do
    
    #Is this the position that is supposed to be overwritten?
    if  tick(:over) == (range 0, length)[position]
      
      #insert the desired value here
      outlist = outlist + (ring value)
      
    else
      
      #copy the value from the original list and insert it here
      outlist = outlist + (ring list.look(:over))
      
    end
    
  end
  
  #return the return list
  overwrite = outlist
  
end

#demonstration
puts overwrite((knit, 5, 5), 5, 1, 3)

Me:

r = (knit 5,5)
l = r.to_a
l[1] = 3
print l.ring
1 Like

Why is stuff like that not mentioned in the sonic pi documentation?
Isn’t there stuff that isn’t officially supported and might be removed in the future?

Most likely because to_a is not considered part of the Sonic Pi language. (Sonic Pi is not designed to be a superset of Ruby but rather a specific DSL built with Ruby).

(It would of course be good for the distinction to be clear in the documentation - It is my goal in the not too distant future to update the documentation to make clearer the differences between Sonic Pi and plain Ruby, and things like the fact that any plain Ruby might still work but is not officially supported or guaranteed to keep working :+1:)

Does this mean that if I want my program to keep working, I should go with the former method?

Does this mean that if I want my program to keep working, I should go with the former method?

Your method, while it is a bit longer, is better in terms of forward compatibility. If you find yourself using it a lot you could put it in ~/.sonic-pi/config/init.rb so that it’s accessbile from all of your buffers. Don’t forget to copy it back in to the buffer if you share it with others though.

All that being said, I don’t think anyone needs to worry too much about compatibility right now as it feels like we’re some way off moving away from Ruby completely. I’ve certainly got a lot of old experiments that rely heavily on it and I’m not too concerned right now. We (the dev team) will try to give as much warning as we can with what will happen but it’s all just discussions and experiements at the moment.

I will say that, having talked to Sam about this in the past, there are actually some good things that could be made possible as a result of not using Ruby in Sonic Pi scripts itself. For example the threading model is wildly complicated at the moment and that’s partly to keep track of all the state in each thread. Using define :foo (like you were doing) instead of def foo (the Ruby way) does open the door to having better code to manage threading, which in turn paves the way to adding more cool features. It’s a long term investment though so I’m afraid it will require some patience all round. I hope that explains things a little bit!

5 Likes