Simple question but there are so many things to consider in make that it feels better if I ask this question:
Is VARIABLE = value equal to VARIABLE=value?
Just FYI, although VARIABLE := value is the same as VARIABLE:=value, but
VARIABLE:=$(undefined) value
# now VARIABLE is prepended with a space
is NOT. This is why the make's manual says "ignored immediately after equal sign".
Also, operator += always adds a space.
Yes, they're the same. Per the docs:
Whitespace around the variable name and immediately after the ‘=’ is
ignored.
Related
Every single time I load my program, even for the fist time, it says
file.rb:9: warning: already initialized constant W_mum
file.rb:6: warning: previous definition of W_mum was here.
a little help here?
W_mum = gets.to_i
elsif (W_mum = 1)
Ruby uses two different "storage bins" for data: variables and constants. In your source code, you can identify them y their first letter: constants always have a capital letter at the start of their name, variables a lower-case letter.
In your case, you thus have a constant named W_mum. Now, when you first set a value to a constant and then later set a different value to it, Ruby will show a warning (as such: you can set new values to constants, but you should not).
Now, as for why Ruby warns here: in your elsif, you are actually assigning the constant the value 1. This might be a bug though. Instead of an assignment with =, you likely intended to use a comparison here, using the == operator.
I'm trying to run a FOR loop on robot framework depending of the status of another variable.
${STATUS1}= Run Keyword And Return Status Should Be Equal As Strings ${CELLVALUE} ${EXPECTEDVALUE}
\ ${COUNT}= Set Variable If '${STATUS1}' == 'True' ${COUNT}+1
\ ... '${STATUS1}' == 'False' ${COUNT}+0
But all I get is '''0'+0'+0'+1 or similar, even if I use Run keyword If and Evaluate instead of set var, I tried to convert to integer but nothing happens and I cannot convert it to integer or number. Any suggestions? thanks in advance!
It looks like you're simply wanting to increment ${COUNT} if ${CELLVALUE} equals ${EXPECTEDVALUE}. That can be done pretty easily with Set Variable if
If you know that ${CELLVALUE} and ${EXPECTEDVALUE} are of the same internal type (eg: strings or ints), and you're using robot framework 2.9 or greater, you can write it like this:
${COUNT}= Set variable if $CELLVALUE == $EXPECTEDVALUE
... ${COUNT+1} ${COUNT}
This assumes that ${COUNT} is initialized to an integer value, which you can do by assigning it the value ${0}
If you don't know the type, can't guarantee the type, or are using an older version of robot, you can use triple-quoted strings to coerce the values to strings:
${COUNT}= Set variable if '''${CELLVALUE}''' == '''${EXPECTEDVALUE}'''
... ${COUNT+1} ${COUNT}
Of course, you could use Run Keyword and Return Status like in your example, and then compare the status. That seems like an unnecessary extra step, but it might make sense in your actual test.
The point being, you can use Set variable if and extended variable syntax to solve this problem.
Note 1: With Set variable if, two values are provided. The first value is assigned if the expression is true, the second one is assigned if the value is false. The second value is the original variable, meaning it won't be changed. If you don't provide the second value, the variable will be set to None.
Note 2: Putting an expression inside curly braces (eg: ${COUNT+1} is documented in rule 4 of extended variable syntax.
Note 3: Starting with robot framework 2.9, variables are available in the evaluation namespace with the simplified syntax $varname. So, the robot variable ${CELLVALUE} can be used in python expressions as $CELLVALUE. This is documented in the section Evaluating Expressions in the BuiltIn library documentation.
In the books I'm reading, I always see
def initialize (side_length)
#side_length = side_length
end
If the object variable always equals the variable with the same name why not write the language to just equal it without having to type it out?
For example:
def initialize (side_length)
#side_length # this could just equal side_length without stating it
end
That way we don't have to type it over with over.
In the example given:
def initialize(side_length)
#side_length = side_length
end
The #side_length = side_length is just an assignment, passing the available argument to an instance variable, in this case it happens to be the same name as the argument.
However those two values don't have to have same names - it's usually named that way for readability/convention reasons. That same code could just as easily be:
def initialize(side_length)
#muffin = side_length
end
The above code is perfectly fine, it just wouldn't read as well (and might slightly confuse someone giving it a first glance). Here's another example of the argument not being assigned to an instance variable of the same name.
It would be possible to write the language in a way which assumes that the argument variable should automatically be assigned to an instance variable of the same name, but that would mean more logic for handling arguments, and that same assumption may result in more restrictions for the developer, for example, someone who may actually want to assign side_length to #muffin for whatever reason.
Here's a SO question similar to this one - the accepted answer provides an interesting solution.
Hope this helps!
It is because "the object variable [does not] always [equal] the variable withthe [sic] same name".
Why doesn't this code work?
b if b = true
Error: undefined local variable or method `b'
But this does:
if b = true
b
end
Shouldn't they be the same?
This is a very good question. It has to do with the scoping of variables in Ruby.
Here is a post by Matz on the Ruby bug tracker about this:
local variable scope determined up to down, left to right. So a local variable first assigned in the condition of if modifier is not effective in the left side if body. It's a spec.
In the first version as soon as k is hit, the parser pukes because it hasn't been seen yet.
In the second version, k is part of an assignment expression, and is parsed differently.
I don't know the reason but the problem that the interpreter tries to lookup the variable k before evaluating the condition.
If you write it like this, there won't be any error and works as you expected:
k = nil
h = {k: 1}
v = k if k = h.delete(:k)
you have put only one '='
Try with '=='
Then you will get error
In second example, you are assigning 'true' to b.
Because the Ruby interpreter creates a local variable when it sees an assignment
In the second case, it hasn't yet seen the assignment, so the variable doesn't exist when the expression is parsed.
To be more precise, a method is first parsed into an internal representation, and then, perhaps, the code will eventually be called and actually executed.
Local variables are created in that parsing pass. It's a matter of declaration, it just means that the interpreter becomes aware of them. They won't be created in the sense of being given space or a value until the surrounding method is called by someone.
I have been trying to do ruby string comparision which doesnt seem to work
max == "value"
if user.name == max
I also tried using the eql method but nothing seems to work
max.eql(user.name)
This is not working althought the values are same.
What could be the reason?
This is because of white spaces. Try doing
if user.name.strip == max
strip will remove all the white spaces
Ruby use the same semantics as C when it comes to assignment versus comparison.
x = y
will assign x the value of y Even if this is done inside an if expression.
The second attempt to use eql (which really should be eql?) will fail, as x.eql?(y) returns true if the x and y are the same object. It is not sufficient that they have the same value.
Note, that in a language like Ruby, many variables can be bound to the same object. If you update the object destructively, this will be reflected on all variables bound to the same object. On the other hand, it will not affect variables bound the another object, even if that object happened to have an equal value as the first object.
Update: The poster changed the question after this answer was posted.