Glad You're Ready. Let's Get Started!

Let us know how we can contact you.

Thank you!

We'll respond shortly.

  • Blog Navigation
Hash#fetch for fun and profit

I have an app where I set the alt tag of images with javascript. To reduce the size of the page, I want to emit img tags with no alt attribute, however that is not currently possible:

image_tag "foo.png", :alt => nil # => <img alt="Foo" src="/images/foo.png" />

I agree that images should have alt tags, and I agree that the Rails default is sensible. However, if I explicitly send :alt => nil, I expect it to omit the alt attribute altogether, to be consistent with :class and other html attributes.

This happens because under the hood the code looks like this:

options[:alt]     ||= File.basename(src, '.*').capitalize

See the issue? If options[:alt] is falsey, the default is used. Since nil is falsey, there’s no way to get options[:alt] to be nil. My requirement is:

  • If I pass an :alt attribute (even if it’s nil), use the passed in value
  • If I pass no :alt attribute, use the default

Making this happen is very simple with the marvelous Hash#fetch:

UPDATE: Thanks to Brennan Falkner and Mark-Andre Lafortune for pointing out the block syntax of fetch is the preferred way.

options[:alt] = options.fetch(:alt) { File.basename(src, '.*').capitalize }

Instead of evaluating the truthiness of the :alt value, fetch checks for the existance of the :alt key. For those of you who are interested in getting this into rails core, apply the patch and give a +1 to the related Lighthouse Ticket.

  • Brennan Falkner

    One of the advantages of the first form is that the expression won’t be evaluated if :alt is set. You may want to allow..
    options[:alt] = options.fetch(:alt) {File.basename(src, ‘.*’).capitalize)}

  • Jeff Dean

    Brennan – thank you. I’ve updated the post.

Share This