Why does a variable with no value return true with

2019-07-16 05:35发布

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

2条回答
闹够了就滚
2楼-- · 2019-07-16 05:52

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.

查看更多
趁早两清
3楼-- · 2019-07-16 05:57

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".

查看更多
登录 后发表回答