在Ruby 1.9中对attr_accessor执行alias_method_chain时保留可见性

时间:2009-11-27 02:33:51

标签: ruby ruby-1.9

我正在尝试从ruby 1.8移植一个库。我没有写图书馆。如果绝对必要,我可以更改API,但它确实有相当数量的用户,我不希望给您带来不便。

这是简化的问题:

require 'rubygems'
require 'activesupport'

class Foo
  private
  def self.attr_accessor_with_magic(*attrs)
    attr_accessor_without_magic(*attrs)
  end

  public
  class << self
    alias_method_chain :attr_accessor, :magic
  end

  attr_accessor :bar
end

foo=Foo.new
foo.bar=17
puts foo.bar

在Ruby 1.8.7p174上,这会打印17

在Ruby 1.9.1p243上,我得到private method ``bar=' called for #<Foo:0x000000010a40f8> (NoMethodError)

显然,Ruby 1.9的行为是正确的。为了更好地说明Ruby 1.8错误,请在上面的代码中用public替换private。 Ruby 1.8仍然打印17

因此,我可以通过编写

来保留与当前版本库的“bug兼容性”
  private
  def self.attr_accessor_with_magic(*attrs)
    public
    attr_accessor_without_magic(*attrs)
    private
  end

有没有人知道如何做正确的事情并为attr创建适当的可见性?在Ruby 1.8上,无论我做什么,它都会是public,但是有可能为1.9做正确的事吗?

1 个答案:

答案 0 :(得分:0)

如果attr_accessor没有为您做正确的事,您不需要使用它。据我所知,编写attr_accessor :bar只是快速定义两个公共方法的方法,“bar”和“bar =”获取并设置成员变量@bar。因此,您可以手动执行此操作,并为其添加自己的自定义设置和隐私级别:

class Foo
  public
  def bar
    reading_bar_magic()
    return @bar
  end

  private
  def bar=(value)
    setting_bar_magic()
    @bar=value
  end
end