类似于attr_reader的Ruby方法

时间:2010-02-05 03:03:41

标签: ruby metaprogramming

我正在尝试创建一个类似于attr_reader的方法,但我似乎无法获取该方法被调用的类的实例。

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

2 个答案:

答案 0 :(得分:1)

我不确定你要做的是什么。

如果有帮助,attr_reader的咒语是这样的:

#!/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"

答案 1 :(得分:1)

我可以从您的代码中了解到,您希望让modify块响应Klass的实例方法,这很简单:

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

关于这段代码:

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

这可能会给你一些暗示:

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

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

当您向Module类添加方法时,您还要向Class类添加方法,这将为Class的实例添加实例方法(在这种情况下, class Klass),最后这意味着您要在Klass类上添加类方法