I'm just getting into Ruby and come from the Java and C/C++ environment.
While coding a first little project in Ruby, I somehow got used to let all local variables start with an underscore. I guess my main motivation for this was a better readability and distinction from method calls.
As in principle there are only three types of variables ($global
, @instance
and local
), the vast majority of variables start with an underscore. I'm not really sure, whether this is good or bad. Besides, in a lot other languages, the underscore would be substituted to some other character.
Is there somehow a best practice concerning variable naming beside the usual CamelCase and/or underscore separated? What are the habits of the professional "rubyists"? Have I overlooked some general Ruby conventions, when I chose the leading underscore?
edit
Thanks to all answers and suggestions. It helped me a lot.
Short Summary of Answers and Comments below
(for the short-on-time visitor)
Leading underscores go with:
def my_method(_my_arg)
my_array.each { |_x| puts _x}
All other local variables without leading underscores, as programmers coming from e.g. JavaScript might get confused about intended behaviour of the variables.
For visual separation between variable names and method calls, forcing oneself to use "(
" brackets ")
" with all method calls might increase readability significantly.
_ usually means something private or internal. In C++ standard libraries all implementation specific variables must start with _ .
Variable names should not start with underscore ( _ ) or dollar sign ( $ ) characters, even though both are allowed. This is in contrast to other coding conventions that state that underscores should be used to prefix all instance variables. Variable names should be short yet meaningful.
If you have many places where you are using _ as a convention then all of that will break. Using underscore in a variable like a_b is still valid. But using _ alone as variable name is no more valid.
Explanation: Variable names should not start with a number. 5. Why are local variable names beginning with an underscore discouraged? Explanation: As Python has no concept of private variables, leading underscores are used to indicate variables that must not be accessed from outside the class.
Existing answers to this question are now a few years old, and conventions have changed. You should only ever use a leading underscore (_some_param
), or a standalone underscore (_
), to indicate that you don't care about the value. The rubocop style linting tool will carp about a "useless assignment" if you assign a variable but don't use it, but it will ignore variables with a leading underscore. This allows you to expressly indicate that you don't care about the value and don't intend to use it.
Here's a somewhat-contrived example use-case in an RSpec context:
describe 'login' do
let(:user) { FactoryGirl.create(:user, login: 'bob') }
it 'must be unique' do
_user1 = user
user2 = User.new login: 'bob'
expect(user2.valid?).to be_false
end
end
Here we're indicating that our user
helper has a side-effect and returns something, but we don't care about it. You could also just skip the assignment entirely, but seeing a bare user
on a line by itself looks odd and doesn't reveal the intention as clearly:
describe 'login' do
let(:user) { FactoryGirl.create(:user, login: 'bob') }
it 'must be unique' do
user
user2 = User.new login: 'bob'
expect(user2.valid?).to be_false
end
end
Other scenarios include ignoring values in iterators, or overriding a method where you want to keep the original method signature but don't care about some of the values:
def greet(name, _title)
puts "Hi, #{name}!"
end
Nothing wrong with your idea. But if I was having trouble distinguishing local vars from method calls, I would probably just force myself to always use ()
's on methods. (My team at work has discussed making this part of our coding standards).
a = thing # var
b = thing() # method
The possible advantage to this is readability to others. Someone may wonder at your leading _'s, but using ()
's on all method calls should be clear to everyone.
In my experience, underscore-prefixed variables in Ruby are much like underscore-prefixed variables in JavaScript: a "don't touch" flag. More specifically, they are used when the implementer is doing something that really is not supposed to be understood as a part of the object, or shouldn't be thought of as the conceptual interface of the object.
This is more clear in the JavaScript world, where somebody is emulating "private" by prefixing a variable with an underscore. They are encoding that there's part of the object that's under the hood and can be ignored when looking at the object from the outside.
In Ruby, I've only really seen this with things like a cache or a singleton instance - the kind of thing that should be invisible to consumers of your object. Non-underscored variables are things that people using your object might be interested to know are there.
In any case, they seem fairly rare, and I would avoid them unless you want to send a signal to the next guy that's coming along that there's some extra magic or voodoo happening.
As far as making a distinction for method calls, if you're worried that there can be confusion between a method and a local variable, I would call the method on self
to clarify. For instance:
def foo
...
end
def some_method
foo # method
bar # variable
end
If this seems unclear for whatever reason, you can clarify with
def some_method
self.foo
bar
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With