Constant Shuffle

Today, another snippet from the category don't try at home, might have unforeseeable consequences!

Constant assignment┬╣ is not permanent in Ruby, so it is perfectly valid to do this:

module A

class B
  def initialize
    p 42

A, B = B, A
# warning: already initialized constant A
# warning: previous definition of A was here
# warning: already initialized constant B
# warning: previous definition of B was here  #=> #<B:0x00000002744008>
# 42

┬╣ As a side note: There is also Module#remove_const, which will delete the constant, but not the module! Quoting the documentation: "If that constant referred to a module, this will not change that module's name and can lead to confusion"

o = Object.send(:remove_const, :Object)
Object.constants # NameError: uninitialized constant Object
o # => Object

The Ruby Shuffle

Developing the swapping idea further, for maximal confusion:

require 'stringio'
def shuffle_ruby(n=rand(50))
  mod, os, e, sio = Module, ObjectSpace, Exception, StringIO
  stderr, $stderr = $stderr,
      m1 = os.each_object(mod).to_a.sample
      m2 = os.each_object(mod).to_a.sample
      puts "Swap #{m1} and #{m2}"
      eval "#{m1}, #{m2} = #{m2}, #{m1}"
    rescue e
  $stderr = stderr
  puts "Ruby shuffled (#{n} swaps)"

More Idiosyncratic Ruby