Okay this has been lingering in my head for quite a while now.
In ruby on rails unit testing there is an exclamation mark with the assert method. Here is an example
test "No empty values to be inserted" do
product = Produce.new
assert !product.save
end
Let me know the function of the exclamation mark. Quick replies appreciated. Thanks.
! is Logical negation.
If product.save is truthy (that is, neither nil nor false), !product.save returns false.
If product.save is falsy (that is, either nil or false), !product.save returns true.
Therefore, assert !product.save means that product.save must return falsy for the test to pass.
Related
I have the following condition:
if "FIX_STRING 0,0,DYNAMIC_STRING" == "FIX_STRING #{integer_from_0_to_5},#{integer_from_0_to_5},#{DYNAMIC_STRING}"
true
else
false
end
How to make it dynamically like this?
if "FIX_STRING 0,0,DYNAMIC_STRING" == "FIX_STRING #{/0|1|2|3|4|5/},#{/0|1|2|3|4|5/},#{/A|B|C|D/}"
true
else
false
end
You're on the right track here, but you've got a very peculiar coding style. The first thing to point out is that a comparison like == already returns a boolean value of true or false, there's no reason for the if which then returns exactly the same thing.
The second thing is that you're comparing a string to another string, so they have to match exactly. Close enough does not count. If you evaluate your other string you get a mess:
"FIX_STRING (?-mix:0|1|2|3|4|5),(?-mix:0|1|2|3|4|5),(?-mix:A|B|C|D)"
Finally, if you're trying to test a string versus a regular expression, you do this:
PATTERN = /\AFIX_STRING [0-5],[0-5],[A-D]\z/
You can test this sort of thing on Rubular to get it right. Here [0-5] means anything in that range. It's short-hand for what you had.
Then you can test arbitrary strings versus this pattern:
"FIX_STRING 3,4,D".match(PATTERN)
# => #<MatchData "FIX_STRING 3,4,D">
So that matched.
Newer versions of Ruby have a match? method that only tests matches, it doesn't return what matched, which you might want to make use of if you're running on 2.3 or later. It's faster than the plain match method, though that only really matters if you're doing a lot of matches inside loops.
What is the proper way to make a conditional which checks of something is or is not empty in Lua? if x == "" and f x ~= "" does not seem to work.
Lua is a dynamically type-based language.
Any variable can hold one of the following types: nil, boolean, number, string, table, function, thread, or userdata.
Any variable in a table (including _G, the table where globals reside) without a value gives a value of nil when indexed. When you set a table variable to nil, it essentially "undeclares" it (removing the entry from memory entirely).
When a local variable is declared, if it is not assigned immediately it is given a value of nil. Unlike table variable, when you set a local variable to nil, it does not "undeclare" it (it just has a value of nil).
In Lua, an empty string ("") is still a "value" - it's simply a string of size zero.
I recently ran across this problem as well. LuaSQL was returning empty strings if a database value was 'blank' (not null). A hacky approach, but here's how I solved it:
if (string.len(x) >= 1) then
...
end
I'm going to make an assumption that the OP means "how do you tell when a variable is unassigned".
Example:
local x
The variable x is "empty", it is initialized to "nil". (Not the text "nil", but an enumerated value that indicates that the variable is unassigned. In Lua that is defined as nil, in some other languages it is defined as NULL.)
Now assign x a value.
Example:
x=""
Now x is not nil.
Another example:
x=0
x is not nil.
Try running this code, it should make the situation clear to you.
local x
if x==nil then print("x is nil") end
x=0
if x==nil then print( "This line won't be written") end
x=""
if x==nil then print( "and this line won't be written") end
The first if statement will evaulate to true and the print statement will be called. The 2nd and 3rd if statements are false and the print statements will not be executed.
In conclusion, use "==nil" to check to see if a variable is "empty" (which is more properly said "nil").
You probably have spaces, newlines or other non-visible characters in your string. So you think it is "empty", but it isn't. This typically happens when you are taking input from the user, and has to type "enter" to finish - the "enter" ends up in the string.
What you need is a function that tells you whether the string is "blank" - either empty, or a list of spaces/tabs/newlines. Here's one way to do it:
function isBlank(x)
return not not tostring(x):find("^%s*$")
end
Usage:
if isBlank(x) then
-- ...
end
I've just encountered an interesting piece of code. I'd like to determine if it's a ruby standard or a rails convention.
redirect_to(session[:return_to] || users_path)
This prevents redirect_to :back from causing errors in some cases. In c++ something like that would mean a function with one bool argument. But here it seems to work another way - it takes that argument which isn't a nil I suppose. Can someone explain it to me and show an example definition of such a function, which takes arguments separated by '||'?
Bye
Boolean operators such as || and && return the last evaluated statement.
An example,
puts "hi" && "no"
The above will print "no" since both strings are considered 'truthy' and "no" was the last value called.
In this case the programmer is taking advantage of the short circuit nature of the || operator. So another example,
puts "hi" || "no"
The above will output "hi" since "hi" is considered truthy and or is short circuited "hi" was the last value called from the expression and will be returned.
You will see this kind of construct a lot in ruby, especially with ifs.
a = if true
"A will be set to this string"
else
"This will never happen"
end
puts a #=> A will be set to this string
Edit: As nick mentioned, it is important to note that only nil and false are treated as "falsy". Some interesting examples
a = nil || "hi"
puts a #=> "hi"
a = false || "hi"
puts a #=> "hi"
In these two cases the first argument is "falsy" so the "hi" is evaluated and returned (and then assigned to a)
a = Object.new || "hi"
puts a #=> <Object:0x10832420>
In this case (and for any other value as the first argument) Object.new is "true" and thus "hi" is never evaluated. In your particular example, the author was most likely testing for the presence (not nil) of session[:return_to]. This can be very useful but always remember that it may not work properly if false is a valid value.
This is called Short-Circuit Evaluation and it is common in many programming languages
In plain English, your statement says
"redirect to session[:return_to] if it is present, if not, redirect to users_path"
It calls redirect_to(session[:return_to]) if session[:return_to] is truthy (e.g. not nil or false).
If session[:return_to] is falsy, then it calls redirect_to(users_path).
See http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Operators#Logical_Or.
The logical OR is short-circuited, meaning that if the left-hand side is "true", or non-nil, then the value of the entire expression is the left-hand side, and the right-hand side is never considered. So if session[:return_to] is non-nil, it is the value of the expression. If it is nil, though, then the value of the expression is the value of the right-hand side, i.e. the value of user_path.
You can even write things like x || x = "foo", in which case x only gets reassigned if it was nil to begin with, but won't be touched if it is non-nil.
As for the function, it just takes a string, and it doesn't care what you plug in to the argument.
I want validate many mails ( one or more) with regex expression but this attribute donĀ“t belongs to any model. So I wrote a method:
def emails_are_valid?(emails)
#regex with validation
regex = Regexp.new("^(\s*[a-zA-Z0-9\._%-]+#[a-zA-Z0-9\.-]+\.[a-zA-Z]{2,4}\s*([,]{1}[\s]*[a-zA-Z0-9\._%-]+#[a-zA-Z0-9\.-]+\.[a-zA-Z]{2,4}\s*)*)$")
#if the quantity of emails is zero o its validations is bad return false.
if emails.blank? || emails.match(regex).nil?
return false
else
return true
end
end
I evaluate this string mm#somedomain.com aa, mma#somedomain.com when
I tested this regex in http://www.rubular.com/ is bad (no matches).
So According to this page my regex is ok.
But when I evaluate emails.match(regex).nil? that returns me false (So the string is valid, but this string is bad)
Please I need help. my regex is bad or my emails_are_valid? method is bad or match method is bad.
Thanks in advance.
You should have used single quotes instead of double quotes when declaring your regex, otherwise \s gets parsed as an escape sequence.
Change that line to
regex = Regexp.new('^(\s*[a-zA-Z0-9\._%-]+#[a-zA-Z0-9\.-]+\.[a-zA-Z]{2,4}\s*([,]{1}[\s]*[a-zA-Z0-9\._%-]+#[a-zA-Z0-9\.-]+\.[a-zA-Z]{2,4}\s*)*)$')
and the method will work.
On a side note, this would be a more concise way of doing the same thing - http://codepad.org/YbsqIkcP
Why is the second if statement failing in the following code block? The output from the console indicates that the private parameter is 0, so it should be passing? The private parameter is from a checkbox in the new form, that I'm using to set a boolean field in the model.
if (((params[:note])[:text]) != "")
logger.debug("passed first test")
logger.debug(((params[:note])[:private]))
if (((params[:note])[:private]) == 0)
logger.debug("passed second test")
end
end
console output
passed first test
0
Completed in 61ms (DB: 1) | 302 Found [http://localhost/notes]
Thanks for reading.
Form fields are submitted as strings so params[:notes][:private] will actually contain "0" not 0.
You could use either params[:notes][:private] == "0" or params[:notes][:private].to_i == 0 to get the comparison you're after.
If you want to treat non-integer values (including empty strings and missing values) differently from 0, you should not use String#to_i. I would recommend checking the String value in these cases.
You can use Object#inspect (as mentioned by #sepp2k) and Object#class when debugging to get a better idea of what types things are. When using script/console, I find ap (or pp) to be rather handy.
A side note: In Ruby you don't need so many parentheses. Here's the your example after a little bit of cleanup:
unless params[:note][:text].blank?
logger.debug "passed first test"
logger.debug params[:note][:private].inspect
if params[:note][:private].to_i == 0
logger.debug "passed second test"
end
end
In cases where two expressions print the same, but aren't equal, you usually have different types. For example "0", :"0" and 0 both print as 0, but aren't actually equal to each other.
logger.debug(params[:note][:private].inspect) should give you more meaningful output, indicating the type of the object as well as the contents (i.e. if it's a string it's surrounded by quotes, if it's a symbol it starts with a colon, etc.).
The values in params are generally strings, so the value of params[:note][:private] is very probably "0", not 0.