-1

Why does this little code snippet (for a navigational helper with css classes) give me an undefined method 'include?' for nil:NilClass on the elseif-line?

The page_classes_string may be something like 'oddchap oddchap_zoidberg oddchap_zoidberg_index'. I think the purpose of this method is clear:

  1. Get rid of the last word in the page_classes_string if it contains '_index'
  2. Compare the page_classes_string to the current page_string and return a string with an appropriate class name for some navigation.

I tried this code in irb and of course it works, but not within my middleman config. I also could rewrite it by using a third variable that gets assigned my `page_classes_string', but that seems kind of cumbersome. Any suggestions?

Of course the _stringattached to the following variable names is for clarification purposes only.

def nav_active(page_string)
  if page_classes_string.match(/_index/)
    page_classes_string = page_classes_string.split(/ /)[0..-2].join(' ')
  end

  if page_classes_string == page_string
    'active'
  elsif page_classes_string.include? page_string
    'semiactive'
  else
    nil
  end
end
deefour
  • 34,974
  • 7
  • 97
  • 90
cseelus
  • 1,447
  • 1
  • 20
  • 31
  • Where are you assigning a value to `page_classes_string`, besides in the conditional? – Michael Stalker Feb 06 '13 at 02:18
  • `page_classes_string` itself is a helper that contains a string with all names of the currently open page-tree concatenated and is definitely never empty. – cseelus Feb 06 '13 at 02:25
  • 2
    Check again - it's clearly `nil` at least sometimes. Is `page_classes_string` the name of a method? If so, you should probably avoid assigning a value to a variable of the same name. – Zach Kemp Feb 06 '13 at 04:03
  • I guess I got the scope of vars wrong. Thought inside my method I can use every name that I like, even if it is assigned to a helper, outside of my method. – cseelus Feb 06 '13 at 20:28

1 Answers1

1

I would suggest getting rid of the page_classes_string and simply make a new class to hold your css classes. Depending on how you are currently generating the page_classes_string, I don't imagine this would be too disruptive:

class PageClassCollection
  attr_reader :css_classes

  def initialize(*classes)
    @css_classes = classes
  end

  def to_s
    css_classes.join(' ')
  end

  def non_index_classes
    css_classes.select {|c| !c['_index']}
  end

  def nav_active?(page_string)
    return 'active' if non_index_classes == [page_string]
    return 'semiactive' if non_index_classes.include? page_string
    nil
  end
end

You would use it like this:

page_classes = PageClassCollection.new('oddchap', 'oddchap_zoidberg', 'oddchap_zoidberg_index')
page_classes.nav_active?('oddchap') #=> 'semiactive'

If you still need to convert it into a string, .to_s takes care of that (it will be called automatically if you use string interpolation, e.g. "#{page_classes}").

Zach Kemp
  • 11,736
  • 1
  • 32
  • 46