Reputation: 11
So I wrote a simple product class and instantiated from the class.
#This class defines a product
#It provides a method that can be used to provide a discount on any given instance of a product
class Product
attr_reader :name, :description, :price
def initialize (name, description, price)
@name = name
@description = description
@price = Float(price)
end
def price=(sale_price)
@price = sale_price
end
def to_s
"Name: #{@name}, Description: #{@description}, Price: #{@price}."
end
end
my_product = Product.new("redshoes","These are beautiful",50.00)
my_product.price = my_product.price * 0.50
puts "The new sale price of #{my_product.name} is #{my_product.price}"
I have one problem I need clarification on and that is when i define a method like this :
def price=(sale_price)
@price = sale_price
end
I'm defining the method and assigning it to a variable at the same time . The first line "def price=(sale_price)" is a bit confusing since I wrote it based on research online and books but if I can get a bit of clarification on this it will be helpful.
Upvotes: 1
Views: 119
Reputation: 171
I think it will make more sense if you understand what def
is actually doing. In your example of def price=(sale_price)
, "price=" is the name of the method you're defining on the Product class. When you call my_product.price =
, you're calling the method you defined called "price=".
You don't actually change any value until you set the instance variable @price
equal to the input of your method (the variable sale_price
).
The reason my_product.price
(without the equal sign) works is because you've defined an attribute called :price
using attr_reader :price
, which is a helpful way of giving you read access to the instance variable @price
.
Hope that helps.
Upvotes: 1
Reputation: 8313
This is just the method name.
def set_price(p)
@price = p
end
or:
def price=(p)
@price = p
end
And you call this way:
product.set_price(100)
product.price=(100)
See? No change. The magic shows up when Ruby allows you to omit the parens and add spaces between the equal and the rest of the name:
product.price = 100
This is just an usual method call. Nothing fancy going on.
Upvotes: 1
Reputation: 1511
It's how ruby does setter methods. Keep in mind there's no requirement that the method name and the variable name match, nor for that any assignment actually takes place, though that's probably good practice most of the time.
but you could have:
def confuse=(ignore_me)
puts "Silly human, #{ignore_me} is being ignored!"
end
which would be invoked any time you have
object.confuse = something
and not perform any actual assignment.
Upvotes: 0