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

Let us know how we can contact you.

Thank you!

We'll respond shortly.

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.

  1. Brennan Falkner says:

    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)}

  2. Jeff Dean says:

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

Post a Comment

Your Information (Name required. Email address will not be displayed with comment.)

* Copy This Password *

* Type Or Paste Password Here *