Haseeb Ahmad
Haseeb Ahmad

Reputation: 8730

Whats the difference between method argument with and without underscore _ in Ruby

I try to find out the purpose of underscore in method argument but not find any reason. Like there is a method

def eligible(user)
end

and same method but with an underscore in argument

def eligible(_user)
end

whats the difference between them

Upvotes: 2

Views: 1145

Answers (2)

Alex
Alex

Reputation: 29955

_ has some meaning as part of the ruby syntax.

Ruby will suppress warnings of unused variables that start with _:

# underscore.rb

def unused_variables_check
  _nowarn = "not used, but warning is suppressed"
  notused = "not used"
  used    = "i need it 100%"
  used
end

# $ ruby -w underscore.rb
# underscore.rb:3: warning: assigned but unused variable - notused

Ruby does not complain about unused arguments:

def unused_arguments_check(a, b)
  p a
end
unused_arguments_check("yay", "nup")

# $ ruby -w underscore.rb
# "yay"

Duplicate argument names is an error:

def dup_arguments_check(a, a) end

# $ ruby -w underscore.rb
# underscore.rb:14: duplicated argument name
# def dup_arguments_check(a, a) end

Unless those names start with an underscore. This is a ruby syntax feature, not just a style guide. It is used on occasion to ignore arguments:

def dup_arguments_with_underscore_check(_a, _a, _, _)
  p _a # don't use it after "ignoring". but, i thought, it would be the last `_a`
  p _
end
dup_arguments_with_underscore_check(:x, :lost_i, :y, :n_limbo)

# $ ruby -w underscore.rb
# :x
# :y

_ has some semantic meaning as part of a style guide. Most common meaning is "this is unused variable/argument".

rubocop is a style checker/formatter. It will complain about everything, including unused arguments.

$ rubocop -l
Inspecting 1 file
W

Offenses:

underscore.rb:3:3: W: Lint/UselessAssignment: Useless assignment to variable - notused.
  notused = "not used"
  ^^^^^^^
underscore.rb:9:31: W: [Correctable] Lint/UnusedMethodArgument: Unused method argument - b. If it's necessary, use _ or _b as an argument name to indicate that it won't be used.
def unused_arguments_check(a, b)
                              ^
underscore.rb:16:45: W: Lint/UnderscorePrefixedVariableName: Do not use prefix _ for a variable that is used.
def dup_arguments_with_underscore_check(_a, _a, _, _)
                                            ^^
underscore.rb:16:52: W: Lint/UnderscorePrefixedVariableName: Do not use prefix _ for a variable that is used.
def dup_arguments_with_underscore_check(_a, _a, _, _)
                                                   ^
#                                               ^
#  Hey, rubocop, I'm using the first `_` -------'

By using _ to match a common style, everyone looking at your code, including future self, will have a bit of extra information.


Ruby convention: https://rubystyle.guide/#underscore-unused-vars

Rubocop convention: https://docs.rubocop.org/rubocop/cops_lint.html#lintunusedmethodargument

Upvotes: 2

Eyeslandic
Eyeslandic

Reputation: 14900

It's just code convention to underscore a variable if you're not gonna use it later on. It has no meaning otherwise.

Use _ for unused variables.

from ... https://clearwater.readthedocs.io/en/stable/Clearwater_Ruby_Coding_Guidelines.html#naming

Also see this for further reading on style preferences. https://github.com/rubocop/ruby-style-guide

Upvotes: 3

Related Questions