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.
Related
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.
I am new to Ruby, so please bear my questions in case they might not make any sense. My question is,
A constant is where we assign values that should not be altered. Why is ARGV a constant, when we can pass as many arguments as we want to in it? Are the arguments not the values for ARGV? When we pass arguments to ARGV, are we assigning values or does ARGV already have its own sets of values?
A constant has to have its value newly assigned at some point. If you take the meaning of constant as something that is never newly assigned its value, then there would be no constant at all. A constant is therefore, a relative notion; you cannot define what a constant is without the relevant domain/scope. A constant remains consistant within that domain, but has its value assigned/changed outside of the scope.
In mathematics, suppose some mathematician used a constant A = 3 at some point in their life solving a certain problem. That does not mean that everyone from that point on using the constant A would always have to assume its value to be 3. In mathematics, the domain of a constant can be a single proof, an article, a book, or a convention throughout a subfield, etc.
For a computer program, the domain for a constant is usually the execution lifespan of a program. A constant remains constant relative to the execution of the program. ARGV has its values set prior to the execution of the Ruby program.
The point is that ARGV has constant value for the entire time span your program runs. Another reason is that you are not supposed to change the value of ARGV. From the Wikipedia page titled Constant (computer programming):
[…] a constant is an identifier whose associated value cannot typically be altered by the program during its execution […]
Ruby is a bit special because it allows you to reassign ARGV (as any other constant), although it will issue a warning. The following is valid Ruby code (but please don’t do this):
ARGV = [123]
# warning: already initialized constant ARGV
p ARGV
# [123]
ARGV is a constant array that is defined on initialization of a Ruby script, in which the values in that array are set to the arguments which were passed in to the script itself.
From the ARGF documentation:
ARGF is a stream designed for use in scripts that process files given as command-line arguments or passed in via STDIN.
The arguments passed to your script are stored in the ARGV Array, one argument per element. ARGF assumes that any arguments that aren't filenames have been removed from ARGV
See the documentation for ARGV for more details.
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.
This question already has answers here:
What do ! and # mean when attached to numbers in VB6?
(3 answers)
Closed 9 years ago.
There is the following in some code I'm trying to figure out:
For I& = 1 To...
I'm not familiar with the & after a variable. What does that represent?
After some further research, it looks like the I& is being defined as a type LONG. Now my questions is why would they be doing this? Is it overkill or just legacy code?
The legacy BASIC Language had several ways of declaring variables. You could use data type suffixes ($, %, &, !, or #) to the variable name
x$ = "This is a string" ' $ defines a string
y% = 10 ' % defines an integer
y& = 150 ' & defines a long integer
y! = 3.14 ' ! defines a single
y# = 12.24 ' # defines a double
Legacy. Old-school (pre-.NET) Visual Basic used variable name suffixes in lieu of (optionally) variable types.
You are right - putting an ampersand & after a number or a variable means that it is of a Long 32-bits type.
So the answer is, how many iterations does the loop need - is it possible, that it would exceed 16 bits integer?
With no data type identifier after the i, it is implied to be of the native Integer (the default). Therefore this i is expressed as an Integer, which makes it a 16-bit i.
So, I'd say it is the original developer had this habit of explicitly stating the variable type with &, and whether it was really needed there depends on the number of iterations that the For..Next loop has to support in this case.
Most likely it is either old code ported forward to VB6 from QBasic, etc. or else just a bad habit some individual programmer had from that era. While kind of sloppy its meaning should be obvious to a VB6 programmer, since it can be used with numeric literals in many cases too:
MsgBox &HFFFF
MsgBox &HFFFF&
These display different values because they are different values.
Yes it means Long but it often reflects somebody who fails to set the IDE option to auto-include Option Explicit in new modules when created.
Using symbolic notation (Integer - %, Long - &, Single - !, Double - #, String - $) is an excellent method for variable declaration and usage. It’s usage is consistent with "structured programming" and it’s a good alternative to Hungarian notation.
With Hungarian notation, one might define a string filename as “strFileName”, where the variable name is preceded by a lower case abbreviation of the variable type. The is contrary to another good programming practice of making all global variables begin with an upper case first letter and all local variables begin with a lower case. This helps the reader of your code instantly know the scope of a variable. Ie. firstName$ is a local string variable; LastName$ is a global string variable.
As with all programming, it’s good to follow conventions, ..whether you define your own conventions or somebody else’s conventions or industry conventions. Following no conventions is a very poor programming practice. Using symbolic notation is one type of naming convention.