在Ruby中的块中保存实例变量

时间:2014-04-09 18:35:54

标签: ruby block instance-variables

当我调用lambda @description时,我看不到实例变量@model的值。这可能吗?我只看到“非常好”。当我打电话给show_description。 提前谢谢。

class Car
  def initialize(model)
    @model = model
  end

  def description
    @description = lambda{yield}
  end

  def show_description
    @description.call
  end
end

c = Car.new("Ford")
c.description{"#{@model} is very good."}
puts c.show_description # => " is very good."

3 个答案:

答案 0 :(得分:3)

c.description{"#{@model} is very good."}不会告诉你你想要什么。 Point是,您传递的块可以访问外部范围,其中未找到变量@model,因此@modelnil。它被称为封装,因此,外部世界无法直接知道/访问对象的状态,在您的情况下,对象是c。对象的 state 表示实例变量的值位于对象c中。但是使用方法,您可以读取/更新对象的状态。

这样做c.description{"#{c.model} is very good."}

您的代码可以重写为:

class Car
  attr_reader :model

  def initialize(model)
    @model = model
  end

  def description
    @description = yield
  end

  def show_description
    @description
  end
end

c = Car.new("Ford")
c.description{"#{c.model} is very good."}
puts c.show_description
# >> Ford is very good.

答案 1 :(得分:1)

你可以这样做:

class Car
  attr_reader :model

  def initialize(model)
    @model = model
  end

  def description
    @description = lambda{yield}
  end

  def show_description
    @description.call
  end
end

c = Car.new("Ford")
c.description{"#{c.model} is very good."}
puts c.show_description #Ford is very good.

答案 2 :(得分:1)

  1. 由于您将proc实例保存为@description,因此最好通过变量而不是yield来访问它。

    def description &pr
      @description = pr
    end
    
  2. 您需要在适当的环境中评估@description,即Car的实例。

    def show_description
      instance_exec(&@description)
    end
    
  3. 使用上述修复程序,它将按预期工作。

    c = Car.new("Ford")
    c.description{"#{@model} is very good."}
    puts c.show_description
    # => Ford is very good.
    

    顺便说一句,您可以将"#{@model} is very good."简化为"#@model is very good."

相关问题