1

Please tell me what am I doing wrong here. I want to be able to capitalize any string that is being added later in the code through the method titles .

class Book
  attr_accessor :book_title

  def initialize
       @book_title = String.new
     end

  def titles
    book_title.capitalize
  end

end

@book = Book.new
puts @book.titles = "steve jobs"

Because when I execute it, I get undefined method `titles=' for #<Book:0x007fbd25813d98 @book_title=""> (NoMethodError)

psharma
  • 1,279
  • 2
  • 19
  • 47

2 Answers2

2

It's a little unclear as to what you're trying to accomplish. You're adding an attr_accessor for book_title, not for titles (which isn't a variable at all). You need to call

puts @book.book_titles = "Steve Jobs"

in order to set (and print) the title.

If you're trying to pass a title to titles and have that method capitalize the title and set @book_title to that, you need to declare it as an assignment method using =, pass in the parameter title, and actually set @book_title to that. Something like this

def titles= title
  @book_title = title.capitalize
end

Currently your titles method only returns the capitalized local variable book_title, which doesn't exist (it needs the @ to reference the instance variable).

  • Yes but you see I want to capitalize on it too. I was wondering how can I pass it or write on book_title through a method – psharma Feb 11 '13 at 15:14
  • So if later i pass in ```puts @book.titles = "james"``` . It should capitalize james to James also. – psharma Feb 11 '13 at 15:18
  • Edited my answer to be an assignment method. I think that's what you're looking for (though you may need to finesse the capitalization aspect). – Reinstate Monica -- notmaynard Feb 11 '13 at 15:25
  • But it is not accepting a value after = . For example ```puts @book.titles = "steve jobs"``` . And there is already an ``` attr_accessor :book_title``` too. – psharma Feb 11 '13 at 15:26
  • Yes, there is an `attr_accessor` for `book_title` but not for `titles`, so you need to define a reader for `titles`. – Reinstate Monica -- notmaynard Feb 11 '13 at 15:27
  • The program works fine when I write a method as ```def titles(value)``` and ```puts @book.titles("steve jobs")``` . But i need to have it the way i mentioned in the question :). Which is ```puts @book.titles = "steve jobs"```. I hope I am making sense. – psharma Feb 11 '13 at 15:27
  • You are. I edited my answer with the method `def titles= title`, which does what you want. – Reinstate Monica -- notmaynard Feb 11 '13 at 15:30
  • Yes fixing the capitalization aspect is what I need help with. And even if I do an attr_reader for title. It wont be for the method title. – psharma Feb 11 '13 at 15:31
  • I don't think there's a built-in method for title capitalization, so you'll need to write your own. Maybe scan through, find all spaces, and set the next character in upcase (though there are some subtler rules about titles). – Reinstate Monica -- notmaynard Feb 11 '13 at 15:34
  • Here is my updated code - http://pastebin.com/je2j1Zgz . But it doesnt capitalize :P. – psharma Feb 11 '13 at 15:35
  • It capitalizes the way `String#capitalize` does: sets the first character in upper case and the rest in lower. You'll need to write your own capitalizer. – Reinstate Monica -- notmaynard Feb 11 '13 at 15:38
  • but its not even capitalizing the first letter. – psharma Feb 11 '13 at 15:41
  • Check `@book.book_title` -- it should be correct. Apparently Ruby assigner methods return the values they are passed, not the last line in the method (unlike other methods), so the `puts` statement just prints that value. – Reinstate Monica -- notmaynard Feb 11 '13 at 15:46
  • maybe something is wrong on my end. I will look it up. thanks so much :) – psharma Feb 11 '13 at 15:55
0

It's saying "undefined method titles=" because you haven't defined a method named titles=. Instead, attr_accessor (one of Ruby's many misleading names) defines two methods, in your case named book_title and book_title=. Then you add titles. None of these is named titles= (the equal sign is significant).

Your titles method (by the way, you should figure out if it's singular or plural) is redundant with book_title, which will lead to confusion. As someone seeing this code for the first time -- or once again, after a break -- how am I to know which method to call?

You need to decide whether to capitalize the string on the way in (during the setter) or on the way out (during the getter). No matter what you do, I recommend that you stop using attr_accessor for a bit, and just explicitly define a getter and a setter (def title and def title=) until it's clear in your mind what they do. The attr_accessor macro is just a shorthand; you should learn longhand first.

AlexChaffee
  • 8,092
  • 2
  • 49
  • 55
  • Something like this? http://pastebin.com/Jp1dxMa4 . Not working though. It returns the string without capitalizing. – psharma Feb 11 '13 at 15:42
  • When you `puts` *during* an assignment, things get weird (not sure why). Try `@book.title = 'moby dick'; puts @book.title;` (and see my [test-first lab on strings](http://testfirst.org/live/learn_ruby/simon_says) to figure out why the result is `"Moby dick"`). – AlexChaffee Feb 11 '13 at 16:20