In Ruby, how do you set a variable to a certain value if it is not already defined, and leave the current value if it is already defined?
问题:
回答1:
While x ||= value
is a way to say "if x contains a falsey value, including nil (which is implicit in this construct if x is not defined because it appears on the left hand side of the assignment), assign value to x", it does just that.
It is roughly equivalent to the following. (However, x ||= value
will not throw a NameError
like this code may and it will always assign a value to x
as this code does not -- the point is to see x ||= value
works the same for any falsey value in x, including the "default" nil
value):
if !x
x = value
end
To see if the variable has truly not been assigned a value, use the defined?
method:
>> defined? z
=> nil
>> z = nil
=> nil
>> defined? z
=> "local-variable"
>> defined? @z
=> nil
>> @z = nil
=> nil
>> defined? @z
=> "instance-variable"
However, in almost every case, using defined?
is code smell. Be careful with power. Do the sensible thing: give variables values before trying to use them :)
Happy coding.
回答2:
@variable ||= "set value if not set"
So false
variables will get overridden
> @test = true
=> true
> @test ||= "test"
=> true
> @test
=> nil
> @test ||= "test"
=> "test"
> @test = false
=> false
> @test ||= "test"
=> "test"
回答3:
As you didn't specify what kind of variable:
v = v
v ||= 1
Don't recommend doing this with local variables though.
Edit: In fact v=v is not needed
回答4:
A bit late but a working solution that also does not overwrite falsey values (including nil
):
# assuming x is not defined in current scope
!defined?(x) ? x = 42 : nil # => x == 42
y = false
!defined(y) ? y = 42 : nil # => x == false
z = nil
!defined(z) ? z = 42 : nil # => z == nil
回答5:
If the variable is not defined (declared?) it doesn't exist, and if it is declared then you know how you initialized it, right?
Usually, if I just need a variable whose use I don't yet know---that I know will never use as a Boolean---I initialize it by setting its value to nil. Then you can test if it has been changed later quite easily
x = nil
some code
if x do
[code that will only run if x has changed]
end
that's all.