Skip to content

Instantly share code, notes, and snippets.

@nurugger07
Last active August 29, 2015 14:24
Show Gist options
  • Save nurugger07/bb104851f10f84496c57 to your computer and use it in GitHub Desktop.
Save nurugger07/bb104851f10f84496c57 to your computer and use it in GitHub Desktop.

Trivial Example: Compose a meet & greet in Ruby

class Greeter
  class << self
    def meet(person, &block)
      yield person
    end

    # Greet everyone except Johnny
    def greet(person, &block)
      if person == "Johnny"
        yield "Can't talk right now, Johnny"
      else
        yield "Hello #{person}!"
      end
    end
  end
end

Greeter.meet "Johnny" do |person|
  Greeter.greet person do |message|
    puts message
  end
end

Greeter.meet "Brooke" do |person|
  Greeter.greet person do |message|
    puts message
  end
end

The same functionality in Elixir:

defmodule Greeter do
  def meet(person), do: person
  
  def greet("Johnny"), do: "Can't talk right now, Johnny"
  def greet(person), do: "Hello #{person}!"
end

"Johnny" |> Greeter.meet |> Greeter.greet |> IO.puts
"Brooke" |> Greeter.meet |> Greeter.greet |> IO.puts
@oldfartdeveloper
Copy link

As a fan of both Ruby and Elixir, what you have is interesting but not quite equivalent and is therefore not quite fair to Ruby.

This is because I am noticing that you are defining blocks in Ruby that you aren't using. Hence, it seems as the equivalent Ruby to what you're doing in Elixir would look like:

class Greeter
  class << self
    def meet(person) person end
    def greet(person) person == 'Johnny' ? "Can't talk right now, Johnny" : "Hello #{person}!" end
  end
end

puts(Greeter.greet Greeter.meet('Johnny')) # => "Can't talk right now, Johnny"
puts(Greeter.greet Greeter.meet('Brooke')) # => "Hello Brooke!"

So you can see the that LOC for the two versions are much closer together.

That being said, you do gain efficiency with Elixir's pattern matching, and I do like the |> syntax in Elixir.

@nurugger07
Copy link
Author

@oldfartdeveloper my example is contrived to show composition. I wasn't trying to make the Ruby look like Elixir as much as follow the composition. I could argue to that most Rubyist would write that code a little differently, especially once more data transformation was needed. The problem with trivial examples are there are a number of ways to solve the problem but the one you use depends on what you are trying to show.

@rwdaigle
Copy link

rwdaigle commented Jul 6, 2015

I see both sides, but think both are idiomatic of their implementing language and is a fair comparison. Also to consider, less lines of code does not mean better. Though I do think the Elixir example is just as, if not more, readable as the Ruby so it "wins" on both fronts.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment