Reputation: 23
I cannot see the value of the instance variable @model when I call the lambda @description. Is this possible? I only see " is very good." when I call show_description. Thanks in advance.
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."
Upvotes: 2
Views: 1144
Reputation: 118299
c.description{"#{@model} is very good."}
wouldn't show you what you want. Point is, the block you passing, has access to the outside scope, where no variable @model
is found, thus @model
is nil
. It is called encapsulation, due to this, outside world wouldn't be able to know/access directly the state of an object, in your case the object is c
. Here object's state means value to the instance variables lies in object c
. But using methods, you can read/update the states of the objects.
Thus do as c.description{"#{c.model} is very good."}
.
Your code can be re-written as :
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.
Upvotes: 3
Reputation: 168249
Since you are saving the proc instance as @description
, it is better to access that via a variable rather than using yield
.
def description &pr
@description = pr
end
You need to evaluate @description
in the appropriate environment, i.e. within the instance of Car
.
def show_description
instance_exec(&@description)
end
With the fixes as above, it will work as you intended.
c = Car.new("Ford")
c.description{"#{@model} is very good."}
puts c.show_description
# => Ford is very good.
By the way, you can simplify "#{@model} is very good."
to "#@model is very good."
.
Upvotes: 1
Reputation: 17795
You can do it like this:
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.
Upvotes: 1