3

I'm trying to define a class method using two arguments - title and author. When I try to pass my arguments I'm getting an argument error

syntax error, unexpected ',', expecting ')' book.set_title_and_author= ("Ender's Game", "Orson Scott Card")

class Book

  def set_title_and_author= (title, author)
    @title = title
    @author = author
  end

  def description
    "#{@title}was written by #{@author}"
  end

end

book = Book.new

book.set_title_and_author= ("Ender's Game", "Orson Scott Card)

p book.description

Am I not allowed to pass more than one argument in my setter method or is there something else that I'm missing?

user2864740
  • 60,010
  • 15
  • 145
  • 220
  • Check this http://stackoverflow.com/questions/2380796/creating-a-setter-method-that-takes-extra-arguments-in-ruby – Bala Oct 24 '14 at 21:01
  • Parenthesis do *not* create "tuples" in Ruby. Trying to use them as such will result in a syntax error, used with a setter or not. Also, being a class method (which it is not) vs. an instance method/setter (which it is) is irrelevant. – user2864740 Oct 24 '14 at 21:02
  • 1
    Nitpick on your question title, by the way. This isn't a class method, it's an *instance* method. The term "class method" is reserved for methods like `Book.new` that are called on the class itself. – histocrat Oct 24 '14 at 21:05

3 Answers3

4

You indeed can't pass more than one argument to a method that ends in =. A setter method doesn't need to end in =, though, naturally: you can just do set_title_and_author(title, author).

Another alternative would be to have the method take an array:

def set_title_and_author= (title_and_author)
    @title, @author = title_and_author
end

#...

book.set_title_and_author= ["Ender's Game", "Orson Scott Card"]

If you do the latter, stylistically I'd recommend removing the set and just calling the method title_and_author=. set is redundant with =.

histocrat
  • 2,291
  • 12
  • 21
0
class Book
  def set_title_and_author(title, author)
    @title = title
    @author = author
  end

  def description
    "#{@title}was written by #{@author}"
  end
end

book = Book.new
book.set_title_and_author("Ender's Game", "Orson Scott Card")
p book.description

but more clear approach will be

class Book
  attr_accessor :title, :author

  def description
    "#{@title}was written by #{@author}"
  end
end

book = Book.new
book.title = "Ender's Game"
book.author = "Orson Scott Card"
p book.description

And finally using constructor for setting attributes (and avoiding unnecessary mutability) is much better

book = Book.new("Ender's Game", "Orson Scott Card")
fl00r
  • 82,987
  • 33
  • 217
  • 237
0

The = sign is unnecessary. Do following:

class Book
  def set_title_and_author(title, author)
    @title = title
    @author = author
  end

  def description
    "#{@title} was written by #{@author}"
  end
end
book = Book.new
book.set_title_and_author("Ender's Game","Orson Scott Card")
p book.description

This worked for me.

Abhishek
  • 6,912
  • 14
  • 59
  • 85
Alberto
  • 1
  • 2