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
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"
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
精彩评论