Skip to content

Comment on Friendly attributes pattern in Ruby

Comments

I don't really like the API design. Perhaps in the rails-world this makes sense, but it looks really strange to me.

    Billing::Plan::Factory.find_or_create_by!(
      name: :pro,
      interval: 1.month,
      amount: 50
    )
It is not only the verbosity or use of trailing '!' in a method for no real reason, IMO, but also things such as "1.month". I understand that rails thrives as a DSL, but to me having a method such as .month on an Integer, is simply wrong. Same with HashWithIndifferentAccess - I understand the point, to not have to care whether a key is a String or a Symbol, but it is simply the wrong way to think about this. People who use HashWithIndifferentAccess do not understand Symbols.

The exclamation mark has a reason: if the newly created records fails validations, an exception is raised. Without the exclamation mark, the error is silenced (and the method returns a falsey value). This is a convention across Rails.

Ruby itself mostly uses it for mutating methods (e.g. #gsub("a", "b") replaces the character a with b in a string and returns a new string, but #gsub!("a", "b") mutates the original.

I understand that rails thrives as a DSL, but to me having a method such as .month on an Integer, is simply wrong

It's not that different from `1.times` or `90.chr` which are vanilla Ruby.

HashWithIndifferentAccess

HashWithIndifferentAccess was an unfortunate necessity to avoid DOS attacks when Symbols used to be immortal. There's no longer a reason to use it today, except for backward compatibility.

when *everything* is an object this kind of syntax makes absolutely sense and is quite convenient

my first thought too, as a rubyist.

Yes, "everything is an object" is an essential insight to understanding ruby.

`1 + 1` in Ruby is syntactic sugar for `1.+(1)`. Nothing wrong about it at all, it's just different from what you're apparently used to. This type of thing isn't even unique to Ruby or even OOP.

This is a typical API design in Ruby, but the post is about a somewhat novel API design than what you're pointing out. To address some of your points:

The exclamation mark is a convention. It is used whenever a method could possibly result in an exception being raised. Sometimes it's instead used for non-idempotent methods.

"3.days", etc are Rails things. A lot of non-Rubyists don't like it but once you use it for long enough you tend to really grow to it.

As for HashWithIndifferentAccess, yes this is generally acknowledged as a mistake in Ruby's design and is rarely used in my experience. Originally, all Ruby hashes were HWIA. When they finally realized this was a design mistake they had to create HWIA for some level of backwards compatibility

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.