user2912496
user2912496

Reputation: 11

Ruby method definition

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

Answers (3)

jgnagy
jgnagy

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

Guilherme Bernal
Guilherme Bernal

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

Some Guy
Some Guy

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

Related Questions