New to Ruby and Rails, syntax question

Going through the rails tutorial, it’s using this syntax.

class Article < ApplicationRecord
  validates :title, presence: true,
                    length: { minimum: 5 }
end

I think that validates is a method, and then each of the things are method params, so in my head it should be written like this

class Article < ApplicationRecord
  validates(:title, presence: true, length: { minimum: 5 })
end

I get that validates is a magic method, so that’s fine. But why is it written the first way? Why that spacing? Why no parens around the method? Why would the param name and the first method param be on the first line, but the length on the 2nd?

Thanks!

The validates method accepts a wide range of argument signatures, and this gives it tremendous flexibility at the cost of some amount of clarity. The way that I think about this particular example is that the presence keyword can take true as well as anything that is ‘truthy’.

In a more shorthand application, this lets you apply the same parameters to a list of attributes:

validates :foo, :bar, :baz, presence: true

validates :foo, :bar, :baz, presence: { some: :argument }

As long as the first level keys get something truthy, then that sets up the individual validator to run, while the second level sets the more specific parameters for that validator.

You can also assign many validators on one attribute, so this way each validator can have its own arguments. You could certainly make each assignment on a new line in your model, but if you think about it, this collapses to a similar structure as the one-liner.

Oh, and I completely missed your question. You can certainly write it the way you did.

When you invoke a method, the parentheses are optional. (You should use them when defining the method, though.)

I suspect the example split the arguments for the second validator to a new line to avoid side-scrolling, no other reason. You can certainly write it on one long line with no bad effects, except maybe your linter yelling at you about line-length.

Parentheses are optional. Feel free to have them.

For what’s goes on the first or second line, it’s just an esthetic preference. You could have 1 argument per line or all of them on the same line, it’s ok, it’s just a matter of preference.

Really feel free to use the syntax that you prefer. There’s no big no-no on that part of the syntax.

First of all, there is nothing magic about it. Ruby has a reputation for being magic but it’s just a regular Ruby method, just like you can define for your own stuff. You can see it here yourself. It certainly is not simple, and is written by folks with a deep understanding of the language, but not magic. While it can feel like magic if you don’t understand it, just keep in mind there is nothing magic going on under the hood. Just clever use of the language to make it a better experience for the users of that method. If you ever want to understand it, it’s all open source so dig in. Reading other people’s code is one of the best ways to learn.

As @D-system said, the formatting is just an esthetic preference. The creator of Ruby has a stated goal of making the programmer “to be happy”:

I hope to see Ruby help every programmer in the world to be productive, and to enjoy programming, and to be happy. That is the primary purpose of Ruby language - Matz

Towards that goal, it is a very malleable language, including the syntax. Things like semi-colons on the end of the line, parens for meth calls (or definitions) are often optional. I think the idea is, flexibility means it can be what the programmer wants it to be, making the programmer happy.

Some folks are bothered by that level of flexibility. They are used to languages that have a very restrictive syntax. Therefore they have layered their own rules they follow on top of the language. This is OK also. While I prefer to make use of the flexibility of Ruby (even wrote an article on the topic a while back), if you want to write it how you suggested because that feel more comfortable to you then go for it! If it makes you happy then you are achieving the primary purpose of Ruby.

As to those specific aesthetic choices, a lot of Rubyist who like a more restrictive syntax are heavily influenced by a tool called Rubocop which in turn is influenced by something called the Ruby Style Guide. This tool will highlight (and often even automatically fix) deviations from the Ruby Style Guide. Specifically the argument alignment and method call with arg paretheses rules lead to the formatting you saw.

Rubocop is a great tool. Especially the metrics and security related cops. But IMHO it’s style and layout related cops are over-zealous. Whoever wrote that tutorial might be following that style guide more strictly than I would have. Follow that guide (or any other) if you want, but feel free to do it your way also if you want. I know I do. And it’s not just me. Even the creator of Ruby once said:

The default setting of RuboCop is very much different from my preference, and some of its rules puzzle me

Rails just recently started incorporating Rubocop and it also is defaulting to disabling many of Rubocop’s rules and only enabling a few that it finds useful so you are in good company if those rules don’t line up to your preferences.

Thanks everyone! Very helpful information here.

I would write it like this:

class Article < ApplicationRecord
  validates :title, 
            presence: true,
            length: { minimum: 5 }
end

but then I also force gpt4 to produce javascript that passes jslint.com :slight_smile: