Idiomatic use of parentheses in Ruby - ruby

array.include? 'foo' or array.include? 'bar'
is a syntax error (unexpected keyword_or). Parentheses solve the problem, but as I'm new to Ruby I've no idea which of the following is considered more idiomatic:
Option 1
array.include?('foo') or array.include?('bar')
Option 2
(array.include? 'foo') or (array.include? 'bar')
Does this come down to personal preference, or is one approach considered more "correct"?

I'd suggest you take a look at the community-driven Ruby coding style guide, here particularly the section on Syntax.
Omit parentheses around parameters for methods that are part of an internal DSL (e.g. Rake, Rails, RSpec), methods that are with "keyword" status in Ruby (e.g. attr_reader, puts) and attribute access methods. Use parentheses around the arguments of all other method invocations. - excerpt from the guide
class Person
attr_reader :name, :age
# omitted
end
temperance = Person.new('Temperance', 30)
temperance.name
puts temperance.age
x = Math.sin(y)
array.delete(e)

Are you sure that is failing? Your initial example works fine for me.
ruby-1.9.2-p290 :002 > array = ['bar']
=> ["bar"]
ruby-1.9.2-p290 :003 > array.include? 'foo' or array.include? 'bar'
=> true
As a matter of fact, if anything could be considered idiomatic it would be that one. The low precedence of or allows this to work when you leave the parens off. This characteristic is something that should make it idiomatic to Ruby (and even Perl, which or is a hold over from).
Option 1 is super clear, but considering you included the parens you really have no need to use or. It's probably better to use ||, which has a high precedence like other operators and is just more common. I think using or for the sake of it looking like english is not a great practice. It has a semantic meaning within the language and is probably best used for those qualities.
Option 2 is silly of course. If you're going to include parens, you might as well use them for the method signature.
Hope this helps.

Avdi Grimm reckons you shouldn't use and or or for boolean logic. You should only and or or for control flow (analogous to if or unless)
According to his recommendation, you should use || instead:
array.include?('foo') || array.include?('bar')

Option 1 is preferred since it's common to other languages as well. Option 2 looks like LISP, which is not popular nowadays.

Related

Ruby - when I should use parenthesis or not when calling a function/method

Is there a clear standard or guide to use or not use parenthesis when calling a function/method?
For example, the following code:
class List < Jets::Stack
sqs_queue(:dead_letter)
end
Should I or shouldn't I use parenthesis? Other example:
class ExampleJob < ApplicationJob
def sqs_event ref(:dead_letter)
end
end
vs.
class ExampleJob < ApplicationJob
def sqs_event ref :dead_letter
end
end
Is there a official guideline I can follow?
There isn't an official standard for Ruby code best practices. However, a set of preferred styles has evolved in the Ruby community. It's a good idea to follow those preferred styles, just because it makes your code more easily readable by other Ruby programmers.
Nick Roz has given you a link to the style guide. I would also recommend that you consider installing and using rubocop. It will give you feedback on when and when not to parenthesize arguments, many other formatting matters such as proper indenting, and which of the often several different syntax options to choose in a particular situation.
To answer your specific question about whether or not to use parentheses for method arguments, the answer is yes, in general. Exceptions are, as the guide says, "methods that have 'keyword' status in Ruby." An example is puts (actually the Kernel.puts method). Most people don't use parentheses here, but the guide states that they are optional.
Another example, as Nick has said (although "methods with keyword arguments" isn't quite correct; in that case the arguments are symbols that represent methods rather than keywords), is attr_accessor, which is actually Module.attr_accessor.
So, as a general rule, if it looks like a "command" (a "keyword," if you will), but is actually a method, omit the parentheses. Otherwise, use them. And if you're not sure of the difference, get in the habit of using rubocop.
In Ruby it is usually optional.
Ruby tends towards minimalism so they are often avoided.
Sometimes they are required such as in rspec expect where
expect a.to be true
has to be
expect(a).to be true
Using no parens or empty parens when calling a method that has a parameter results in ArgumentError unless you a default for the param, i.e.
def a(x=1)
The other consideration is when you want to call a method on the result of something, when you'll need want that method to clearly be on the final result, i.e.
"br" + "own".upcase
brOWN
However
("br" + "own").upcase
BROWN
Finally, as I'm talking about clarity, sometimes it may be better to have them, even when not strictly needed. This is generally in compound expressions, rather than relying on operator precedence, etc. Or if you want an expression that specifically does not get executed by standard operator precedence and you want your own grouping and order of operations, for example:
irb(main):007:0> 5 + 6 * 2
=> 17
irb(main):008:0> (5 + 6) * 2
=> 22
As Nick indicated, the one complication is super where super or super() pass on parms but super(a,b) calls super with... a,b as params
Yes there is
I suppose you are looking for community guidelines since there is not style guides from Ruby core team.
Well, whenever you call a method you should use parenthesis, otherwise it becomes unclear
# bad
x = Math.sin y
# good
x = Math.sin(y)
# bad
array.delete e
# good
array.delete(e)
# bad
temperance = Person.new 'Temperance', 30
# good
temperance = Person.new('Temperance', 30)
However it is recommended to skip them when there is no arguments.
Be careful with super and super() they are different. super without brackets passes all the parameters implicitly. super() with empty brackets omits all the parameters
The only exception that comes to my mind is some kind of custom DSL, there must be some rules or preferences for DSL itself e.g.
validates :name, presence: true
It is also true for methods with keyword arguments:
attr_reader :name, :age
According to Matz:
If arguments are given to a method, they are generally surrounded by
parentheses,
object.method(arg1, arg2)
but they can be omitted if doing so does not cause ambiguity.
object.method arg1, arg2

Provide alias for Ruby's built-in keyword

For example, I want to make Object#rescue another name so I can use in my code like:
def dangerous
something_dangerous!
dont_worry # instead of rescue here
false
end
I tried
class ::Object
alias :dont_worry :rescue
end
But cannot find the rescue method on Object:
`<class:Object>': undefined method `rescue' for class `Object' (NameError)
Another example is I would like to have when in the language to replace:
if cond
# eval when cond is truthy
end
to
when cond
# eval when cond is truthy
end
Is it possible to give a Ruby keyword alias done in Ruby?
Or I need to hack on Ruby C source code?
Thanks!
This is not possible without some deep changes to the Ruby language itself. The things you describe are not methods but keywords of the language, i.e. the actual core of what is Ruby. As such, these things are not user-changeable at all.
If you still want to change the names of the keywords, you would at least have to adapt the language parser. If you don't change semantics at all, this might do it as is. But if you want to change what these keywords represent, things get messy really quick.
Also note that Ruby in itself is sometimes quite ambiguous (e.g. with regards to parenthesis, dots, spacing) and goes to great length to resolve this in a mostly consistent way. If you change keywords, you would have to ensure that things won't get any more ambiguous. This could e.g. happen with your change of if to when. when is used as a keywords is case statements already and would thus could be a source of ambiguity when used as an if.

How do I make an operator be evaluated before methods?

If I define an operator,
class Object
def ~#
self || ErrorlessNil.new
end
end
how can I make it so that the ~ is evaluated first, instead of last? Right now, something like
~[1][100].undefined_method
will throw an error, while
(~[0][22]).randomsadfldsf
works fine. The goal is to define a tool that works like coffeescript's question mark. I could make a ?? method but I can't start with a ?, and _? works ok, but that is not fun.
Jörg W Mittag's answer provides one reason it will not work like you want, but there is another reason.
If ~ had stronger precedence than other method application, then
~[0][22].randomsadfldsf
would not be interpreted as
(~[0][22]).randomsadfldsf
but as
(~[0])[22].randomsadfldsf
You can't.
In Ruby, you can only override the behavior of existing operators. You cannot define new operators nor can you change their precedence, arity, associativity or fixity.
This is unlike, for example, Haskell or Fortress, which allow you to define your own operators with your own fixity (prefix, postfix, infix), associativity (left, right, none) and precedence. Ruby is like Python, C# and C++ in this regard.
Obvious and easy answer is that, aside (), you cannot change operator precedence.
However you REALLY want, you can use eval* or/and you can build your Abstract syntax tree (AST)/SEXP.
str = "~[1,2,3].first"
def foo str
if str[0] == '~'
obj, meth = str[1..-1].split '.'
eval "(~#{obj}).#{meth}"
end
end
foo str
foo require that str is in this format:
"<~><object/literal without dot><method without dot>"
With more complex code, foo becomes more complex. You will end with some Regexp or with AST/SEXP.
Build-in Ruby Ripper can change source into sexp. There is gem named Sorcerer. It can change Sexp from the Ripper back to source. However it was tested with 1.9.3 and 2.0 only.
*eval may be insecure because it may run code that you don't want to. Check you string before evaling it!

Define custom Ruby operator

The question is: Can I define my own custom operator in Ruby, except for the ones found in
"Operator Expressions"?
For example: 1 %! 2
Yes, custom operators can be created, although there are some caveats. Ruby itself doesn't directly support it, but the superators gem does a clever trick where it chains operators together. This allows you to create your own operators, with a few limitations:
$ gem install superators19
Then:
require 'superators19'
class Array
superator "%~" do |operand|
"#{self} percent-tilde #{operand}"
end
end
puts [1] %~ [2]
# Outputs: [1] percent-tilde [2]
Due to the aforementioned limitations, I couldn't do your 1 %! 2 example. The Documentation has full details, but Fixnums can't be given a superator, and ! can't be in a superator.
No. You can only define operators already specified in ruby, +,-,!,/,%, etc. (you saw the list)
You can see for yourself this won't work
def HI
def %!
puts "wow"
end
end
This is largely due to the fact that the syntax parser would have to be extended to accept any code using your new operator.
As Darshan mentions this example alone may not be enough to realize the underlying problem. Instead let us take a closer look at how the parser could possibly handle some example code using this operator.
3 %! 0
While with my spacing it may seem obvious that this should be 3.%!(0) without spacing it becomes harder to see.
3%! can also be seen as 3.%(0.!) The parser has no idea which to chose. Currently, there is no way easy way to tell it. Instead, we could possibly hope to override the meaning of 3.%(0.!) but this isn't exactly defining a new operator, as we are still only limited to ruby's parsable symbols
You probably can't do this within Ruby, but only by modifying Ruby itself. I think modifying parse.y would be your best bet. parse.y famtour

Most concise/elegant/appropriate method argument parsing in Ruby

Figured there'd already be an answer to this, but couldn't find one. I've been doing method option parsing a certain way, and wanted to check and make sure it's the most elegant/concise way possible.
This is what I generally do:
def some_method *args
options = args.extract_options!
options.assert_valid_keys(:key1, :key2)
defaults = {:key1 => "one", :key2 => "two"}
options = defaults.merge(options)
general_arguments = args[0]
This, obviously, is designed to allow me to have method calls like:
some_method #user.id, :key1 => "good"
This works, but it seems a bit lengthy for Ruby, and since this is sort of my "general pattern" I wonder if it's really the way I should be doing it. Is there a better, more concise way, or a "more Rubyesque" way, of doing general options parsing?
Assumptions
Aggressive protection– I'm assuming methods are in a public API offered through a gem or gemmable plugin
Defaults are desired mostly to see the patterns others use
Potentially more than one pre-hash non-named parameter accepted
I think it really depends on who or what will be calling this method. If it's a private method, then this is definitely overkill, since all the calls to it will be encapsulated. On the other hand, if it's part of a public API within some gem you are publishing, then I think this defensive approach is appropriate.
If your use case is somewhere in the middle, you might want to take an approach that is a little less defensive, yet slightly explicit. The following is a pattern that I tend to follow when a method is public, but only has a limited number of callers. It requires a fixed number of "general arguments", and a small number of options which have defaults.
def my_method(id, options={})
# Set default options
options[:my_option] ||= "default option"
# rest of your method goes here
end

Resources