2014-04-09 4 views
2

Я не вижу значения переменной экземпляра @model, когда я вызываю лямбда @description. Это возможно? Я вижу только «очень хорошо». когда я вызываю show_description. Спасибо заранее.Сохранить переменную экземпляра в блоке в Ruby

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." 

ответ

1
  1. Поскольку вы сохраняете экземпляр ргос, как @description, то лучше, чтобы получить доступ, что через переменную, а не с помощью yield.

    def description &pr 
        @description = pr 
    end 
    
  2. Вы должны оценить @description в соответствующей среде, то есть в пределах экземпляра Car.

    def show_description 
        instance_exec(&@description) 
    end 
    

С исправлениями, как указано выше, он будет работать, как вы хотели.

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.".

+0

@CarySwoveland Да, это правильно .. 'cvar',' gvar' abd 'ivar' не нужно' {..} ', достаточно только' # '. ** Пример ** - '>> @x = 12 => 12 >>« У меня есть # @ x pens » =>« У меня 12 ручек »' –

+0

Очень приятно, пила и хорошее объяснение. –

+0

Большое спасибо. Метод из BasicObject, я не знал. –

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. 
3

c.description{"#{@model} is very good."} не покажет вам, что вы хотите. Точка - это блок, который вы передаете, имеет доступ к внешней области, где нет переменной @model, таким образом @model - nil. Это называется encapsulation, из-за этого внешний мир не сможет узнать/получить доступ непосредственно к состоянию объекта, в вашем случае объект c. Здесь объект состояние означает значение для переменных экземпляра, находится в объекте 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

Очень хорошее объяснение, Arup. –

Смежные вопросы