Currently, in order to have atomic operations in Ruby you must use my "atomic" gem. Ideally, we'd have VM-level support for atomic operations on instance variables, to enable us to build higher-level concurrency abstractions efficiently.
See https://bugs.ruby-lang.org/issues/8259 if you'd like to contribute to this effort.
>> class Foo
>> attr_accessor :bar, atomic: true
>> end
=> nil
>> hello, goodbye = 'hello'.freeze, 'goodbye'.freeze
=> ["hello", "goodbye"]
>> f = Foo.new
=> #<Foo:0x32f67bbb>
>> f.bar = hello
=> "hello"
>> f.bar_swap goodbye
=> "hello"
>> f.bar
=> "goodbye"
>> f.bar_cas hello, 'world'
=> false
>> f.bar
=> "goodbye"
>> f.bar_cas goodbye, 'world'
=> true
>> f.bar
=> "world"
I'll answer my own lazy question - it returns the old value, where assignment returns the new value.