Alex Balgavy

Just some stuff about me.

Here's my dotfiles repository.

Check out my blog.

My keys: PGP, SSH

My crypto wallets (BTC, XMR)


What links here:

Ampersand/pretzel in Ruby

In Ruby, you might see ampersand syntax, like this:

  [1,2,3].select &:even?
=> [2]

The ampersand takes whatever follows it and calls the #to_proc method. So in actuality, it does :even?.to_proc, and then calls that on every element of the list. If :even?.to_proc doesn’t exist, Ruby will tell you that the elements don’t have such a method, for example if you try to run:

  ['hello', 'there'].select &:even?
=> undefined method `even?' for "hello":String (NoMethodError)

because ruby doesn’t know how to determine if a string is even. As a sidenote, you can define something like this:

class String
  def even?
    self.length.even?
  end
end

And then it runs:

  #+begin_src ruby
  ['hello', 'there'].select &:even?
=> []

Obviously both the strings are odd in length, so you get an empty list.

But back to ampersands. It converts whatever follows into a proc. So for example, you could do something like this to use the ampersand to prepend a string:

  class String
    def to_proc
      proc { |arg| "#{self} #{arg}" }
    end
  end

  [1,2,3].map &"number"

=> ["number 1", "number 2", "number 3"]

Or you could re-use ampersand syntax for integers to multiply by whatever number you give it:

  class Integer
    def to_proc
      proc { |arg| self*arg }
    end
  end

  [1,2,3].map &7

=> [7, 14, 21]

Is it a good idea? Maybe not. But it shows the power of Ruby.