Reputation: 5178
Are default arguments in ruby methods static? This matters when default arguments are meant to be a dynamic date, such as Date.today
. Consider the following example in a rails application:
class User < ApplicationRecord
def eligible_to_vote?(date_of_interest = Date.today)
p date_of_interest
end
end
Will the default date_of_interest
date always be the the same, static date from when I started the rails server?
Or: will it always dynamically grab "today's date" within the context of the date that the eligible_to_vote?
method was called?
I know the following would for sure dynamically grab Date.today
:
# Always dynamically sets `date` variable when no argument passed in
class User < ApplicationRecord
def eligible_to_vote?(date_of_interest = nil)
date = date_of_interest.present? ? date_of_interest : Date.today
p date_of_interest
end
end
What I'm mostly interested in is if default method arguments are dynamically generated or not. Whatever the answer is, it would be nice to have some official reference to answer this question as well. Thanks!
Upvotes: 5
Views: 1774
Reputation: 369458
What I'm mostly interested in is if default method arguments are dynamically generated or not.
It would be trivially easy to test this:
def are_default_arguments_evaluated_every_time?(optional_parameter = puts('YES!')) end
are_default_arguments_evaluated_every_time?
# YES!
are_default_arguments_evaluated_every_time?
# YES!
If default arguments were evaluated at method definition time, this would print YES!
only once, and before calling the method. If default arguments were evaluated only on the first call and then cached, this would print YES!
only once, when the method first gets called.
Whatever the answer is, it would be nice to have some official reference to answer this question as well.
This is specified in section §13.3.3 Method invocation, step h), sub-step 7), sub-sub-step i) of the ISO Ruby Language Specification.
Upvotes: 7
Reputation: 121000
It is dynamic because Ruby is interpreted, not compiled language.
✎ require 'date'
✎ def test param = DateTime.now
puts param
end
✎ 3.times { test; sleep(1) }
2018-12-14T18:10:08+01:00
2018-12-14T18:10:09+01:00
2018-12-14T18:10:10+01:00
Upvotes: 4
Reputation: 3209
it's not static, Date.today is evaluated every time.
Take for example:
def foo(some_var = boo)
p some_var
end
def boo
p "this is boo"
Date.today
end
When you run today
foo
# "this is boo"
# Fri, 14 Dec 2018
foo
# "this is boo"
# Fri, 14 Dec 2018
When you run tomorrow
foo
# "this is boo"
# Fri, 15 Dec 2018
Upvotes: 0