2

The empty? method is undefined for nil class, so when you try nil.empty? in the console it gives: undefined method empty? for nil:NilClass

I created this method in my application_helper.rb:

def full_title(page_title)
   base_title = "my app"
   if page_title.empty?
     base_title
   else
     "#{base_title} - #{page_title}".html_safe
    end
end

In my application layout I call it on the title tag like this:

!!!
%html
  %head
    %title #{full_title(yield(:title))}
    ...
    ...
  %body
    = yield

And in each of my views I add provide(:title, "something") for passing a string to this helper method.

But when I don't use provide(:title, "something") it looks like if page_title.empty? returns true!

My question is why page_title.empty? returns true. I think the page_title variable is nil when I don't use provide(:title, "something"), does it not raise any errors? such as undefined undefined method empty? for nil:NilClass

wpp
  • 7,093
  • 4
  • 33
  • 65
medBouzid
  • 7,484
  • 10
  • 56
  • 86
  • maybe you wanted the #present? method? – rogerdpack Jul 24 '13 at 19:13
  • 1
    you should never be satisfied with just "thinking" your variable is something. just trace it or debug it and you will know for sure – Justin L. Jul 24 '13 at 19:34
  • does `if page_title.to_s.empty?` solve your problem? (if it does not, it is not the `.empty?` we see in the question, which is the problem) – tessi Jul 25 '13 at 13:28
  • thank you tessi for all your answers :) my source of confusion is this call : full_title(yield(:title)), at first time i say full_title() take a symbol :title and if i remove provide(:title, "my title") from my view, logically my test : if page_title.empty? is the same as :title.empty? which result false, but me i expect true because there is no provide(:title, "my title") in my view !! i think it's yield who correct this and return an empty string – medBouzid Jul 25 '13 at 13:39

2 Answers2

1

If you do yield :title and nothing was provided, it will return an empty string, so it can just be concatenated in your view.

If I understand correctly your code just works as it is now. pagetitle is empty, right?

Related: How does the yield magic work in ActionView?

What the given link explains is that each time you do content_for or provide it will build a hash (for instance, it does not really matter how it is stored for real), and when you do yield it will look up the piece of content for the requested symbol. In fact that is all you need to know. But it will never test if the symbol is empty, instead it will test if they have content for the given symbol, and if not, return an empty string.

So an example implementation would be something like

def provide(symbol, args=nil, &block)
  @content_for[symbol.to_sym] = args
  @content_for[symbol.to_sym] ||= capture(yield)
end

and the lookup will look something like

def yield(symbol)
  @content_for[symbol].to_s
end

and nil.to_s is just an empty string.

Now rails is just open source, so you can look it up if you really want, and it will be a little more complicated, definitely regarding the block-handling.

Now symbols are probably complicated to understand. A symbol is a string, which gets a unique number. So each time you write :name it will have the same number (say 1), and each time you write :first_name it will have another number. So symbols are a very readable way to assign unique numbers, and thus are always used to in hashes to store and find stuff. So it is never the symbol itself that has content, the symbol is used as a key to find content in a hash.

Community
  • 1
  • 1
nathanvda
  • 49,707
  • 13
  • 117
  • 139
  • when i add for example this line : provide(:title, "a title for home page") to my home view ---> full_title(yield(:title)) in my layout detect that there is a title with content "a title for home page" and it say ok there is a title i will show it, but when i remove the line : provide(:title, "a title for home page") from my home view ---> it will search for provide(:title...) but no provided title exist anymore then test for page_title.empty? who means that it test for provided title and it find it empty – medBouzid Jul 25 '13 at 13:13
  • at first i think that full_title(yield(:title)) test for a symbol who means it test for :title.empty? and :title.empty is not empty , but i understand now that yield method do some verification but i can't understand how also with the link that you give to me – medBouzid Jul 25 '13 at 13:17
  • i really appreciate your help , i don't know how to thank you for your explanation :) for the last paragraphe of your answer i know what is symbol and i understand it... i think that in rails the only problem is to understand some internal methods and helpers and i find that most people working with features and things they may not even know how they work. I wish one day understand rails deeper ^^. thank you – medBouzid Jul 25 '13 at 22:30
0

If it works, it means that your variable page_title is not nil.

Test it in debug mode and report your findings :)

hint: with pry you can put binding.pry just after base_title = "my app".

a.s.t.r.o
  • 3,261
  • 5
  • 34
  • 41
  • but how it works , i install pry gem, then i add binding.pry after base_title = "my app" as do you say and here i have a stop point in my console, i'm trying to debuggin with puts base_title --> it show me nil , when i do juste base_title it shows me : "" – medBouzid Jul 24 '13 at 20:54
  • We were talking about `page_title`, in pry debug session, just type `page_title`, it should not be nil (puts always return nil, it is completely normal, no need to use it in pry unless you know what are you doing) – a.s.t.r.o Jul 24 '13 at 21:44
  • ok , when i type page_title it return "", but i don't understand why its an empty string and not nil ! this is my question – medBouzid Jul 24 '13 at 23:19
  • Probable because you call `full_title("")` but now we are speculating, please open another question with more details. – a.s.t.r.o Jul 25 '13 at 11:18