"Gray, Jeff" wrote:
...
> Could someone suggest a way to rewrite "inc_iv" without using eval, without
> turning the guts of the each block into a method, and without flattening the
> [:@a, :@b].each{} construct?

Is it cheating to use C?

require 'cgen/cshadow'  # From cgen on RAA

class Bar
  include CShadow
  
  def initialize
    @a = 1
    @b = 2
  end
  
  def inc_iv
    [:@a, :@b].each { |iv|
      iv = iv
      set_iv(iv, get_iv(iv) + 1)
    }
  end
  
  define_method :set_iv do
    arguments :attr, :value
    body %{
      rb_ivar_set(shadow->self, rb_to_id(attr), value);
    }
    returns %{shadow->self}
  end
  private :set_iv
  
  define_method :get_iv do
    arguments :attr
    returns %{rb_ivar_get(shadow->self, rb_to_id(attr))}
  end
  private :get_iv
  
  def inspect
    "<Bar: a = #{@a}, b = #{@b}>"
  end
end

Bar.commit # write to .c files, make, and require

bar = Bar.new
bar.inc_iv
p bar         # ==> <Bar: a = 2, b = 3>

----

There's nothing stopping you from adding these methods to Object, and
once the .so/.dll is generated, you don't have to commit each time. Just
require the library.