0

我正在尝试从 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替换为。privateRuby 1.8 仍然可以打印17

因此,我可以通过编写来保持与当前版本的库的“错误兼容性”

  private
  def self.attr_accessor_with_magic(*attrs)
    public
    attr_accessor_without_magic(*attrs)
    private
  end

有谁知道我如何做正确的事情并为 attr 创建适当的可见性?在 Ruby 1.8 上,public不管我做什么,都可以,但是有可能为 1.9 做正确的事情吗?

4

1 回答 1

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
于 2009-11-27T07:25:28.087 回答