Rings are immutable, so the solution is to build a fresh string.
With your example:
notes = scale :e3,:minor_pentatonic
puts notes # ===> (ring 52, 55, 57, 59, 62, 64)
notes2 = notes[0..1]+[:r]+notes[3..-1]
notes=notes2
puts notes #==> (ring 52, 55, :r, :r, 62, 64)
A function which can do this for you is shown below.
NB the position to replace is numbered from 0 upwards (0 gives is first value in the ring)
notes = scale :e3,:minor_pentatonic
puts notes # ==> (ring 52, 55, 57, 59, 62, 64)
define :update do |n,position,val|
pos =[0, [position, n.length - 1].min].max #set limits to position
#puts pos #for debugging
l=pos-1;r=pos+1 #calc slice positions
#puts "l,r",l,r #for debugging
if l < 0 #special case. Insert val at start of ring
return [val]+n[1..-1]
elsif
r > n.length - 1 #special case insert val at end of ring
return n[0..-2]+[val]
else
return n[0..l]+[val]+n[r..-1] #normal cases
end
end
notes = update(notes,3,:r)
puts notes # ==> (ring 52, 55, 57, :r, 62, 64)
In this example the FOURTH note is replaced counting from 0 this is 0,1,2,3
If you want you can adjust things to count from 1 by inserting line
position -= 1
as the first line in the definition
EDIT the min max methods are used to clamp position so that it is not outside the ring. Otherwise
if you put something like update(notes,400,:r) it would give an error. With the error checking this will replace the last character in the ring.
EDIT 2
you may be able to write this a bit more nicely by using the .take and .take_last methods listed in the Sonic Pi tutorial section shown below
http://sonic-pi.net/tutorial.html#section-8-5