tags:

views:

65

answers:

2

I'm trying to make a method similar to attr_reader but I can't seem to get the instance of the class that the method gets called in.

class Module
    def modifiable_reader(*symbols)
        # Right here is where it returns Klass instead of #<Klass:0x1df25e0 @readable="this">
        mod = self

        variables = symbols.collect { |sym| ("@" << sym.to_s).to_sym }
        attr_reader *symbols

        (class << ModifyMethods; self; end).instance_eval do
            define_method(*symbols) do
                mod.instance_variable_get(*variables)
            end
        end
    end
end

class Object
    module ModifyMethods; end
    def modify(&block)
        ModifyMethods.instance_eval(&block)
    end
end
class Klass
    modifiable_reader :readable

    def initialize
        @readable = "this"
    end
end

my_klass = Klass.new
my_klass.modify do
    puts "Readable: "  << readable.to_s
end
+1  A: 

I'm not sure what it is you're trying to do.

If it helps, the spell for attr_reader is something like this:

#!/usr/bin/ruby1.8

module Kernel

  def my_attr_reader(symbol)
    eval <<-EOS
      def #{symbol}
        @#{symbol}
      end
    EOS
  end

end

class Foo

  my_attr_reader :foo

  def initialize
    @foo = 'foo'
  end

end

p Foo.new.foo     # => "foo"
Wayne Conrad
+1  A: 

What I can understand from your code is that you want to have the modify block to respond to the instance methods of Klass, that's as simple as:

class Klass
  attr_reader :modifiable
  alias_method :modify, :instance_eval

  def initialize(m)
    @modifiable = m
  end

end

Klass.new('john').modify do
  puts 'Readable %s' % modifiable
end

About this tidbit of code:

def modifiable_reader(*symbols)
  # Right here is where it returns Klass instead of #<Klass:0x1df25e0 @readable="this">
  mod = self
  ...

Probably this can give you a hint of what is going on:

Class.superclass # => Module
Klass.instance_of?(Class) # => true

Klass = Class.new do 
  def hello
    'hello'
  end
end
Klass.new.hello # => 'hello'

When you are adding methods to the Module class, you are also adding methods to the Class class, which will add an instance method to instances of Class (in this case your class Klass), at the end this means you are adding class methods on your Klass class

Roman Gonzalez