1

我想知道在没有任何方法的情况下调用对象时是否有办法返回对象而不是字符串。

例如:

class Foo
  def initialize
    @bar = Bar.new
  end
end

有没有办法定义 Foo 类,以便发生以下情况:

foo = Foo.new
foo #returns @bar  

在我感兴趣的特定情况下,我在 Rails 视图中使用演示者。演示者设置一个主要对象,然后加载一堆相关内容。重要的部分如下所示:

class ExamplePresenter

  def initialize( id )
    @example = Example.find( id )
  end

  def example
    @example
  end

  ...

end

如果我想返回 ExamplePresenter 使用的示例,我可以调用:

@presenter = ExamplePresenter.new(1)
@presenter.example

如果我也可以通过调用返回示例对象,那就太好了:

@presenter

那么,有没有办法设置一个默认方法在调用对象时返回,比如 to_s 但返回一个对象而不是字符串?

4

2 回答 2

1

如果我理解正确,您想在Example调用实例时返回ExamplePresenter实例。这种直接机制在任何语言中都不存在,即使存在,它也会阻止对ExamplePresenter实例及其方法的所有访问。所以这不合逻辑。

但是,您可以做一些事情。您可以使ExamplePresenter类将方法委托给其中的Example实例。实际上,您没有得到一个真正的Examplefrom,@presenter但您得到一个ExamplePresenter将所有合格的方法传递到其内部Example有效地代表它行事的一个。

这样做的一些方法是:

方法缺失

class ExamplePresenter
  … # as defined in the question

  def method_missing symbol, *args
    if @example.respond_to?(symbol)
      @example.send(symbol, *args)
    else
      super
    end
  end
end

Example如果ExamplePresenter无法响应,这会将任何方法调用传递给内部。请注意,您可能会以这种方式暴露超出您想要的内部Example内容,并且任何已经定义的方法ExamplePresenter都不能传递。

您可以在内部使用其他逻辑method_missing来限制暴露或预处理/后处理参数/返回值。

包装方法

您可以定义包装方法ExamplePresenter,除了将所有内容传递给 internal 之外什么也不做Example。这使您可以明确控制要公开的数量。

class ExamplePresenter
  … # as before

  def a_method
    @example.a_method
  end
  def another_method(argument, another_argument)
    @example.another_method(argument, another_argument)
  end
end

这很快就会变得乏味,但您也可以添加逻辑来更改参数,然后再将其传递给Example或对结果进行后处理。

也可以混合搭配以上两种方式

委托人

Ruby stdlib 中有一个名为Delegator的库正是为此目的而构建的。你可以调查一下。

于 2011-07-07T19:22:32.600 回答
0

尽管不建议这样做,但您可以执行以下操作:

class Foo
  def self.new
    @bar = Bar.new
  end
end

如果您确实需要创建 的实例Foo,那么

class << Foo
  alias original_new :new
end

class Foo
  def self.new
    self.original_new # It will not be useful unless you assign this to some variable.
    @bar = Bar.new
  end
end
于 2011-07-07T19:20:42.723 回答