I'm trying to use regex as the conditional in a Ruby (1.9.2) if statement but it keeps returning true even when the regex evaluates to nil
if (params[:test] =~ /foo/)
return "match"
else
return "no match"
end
The above returns "match" even when Rails.logger.info(params[:test]) shows test as set to "bar"
if params[:test] =~ /foo/
# Successful match
else
# Match attempt failed
end
Works for me. Debug what is in params[:test]
Related
Working in Rails 4.2 and Ruby 2.3.3
I'm dealing with an API that has an error fiend in certain circumstances but not in other circumstances. I would like to check to see if that error key exists and, if yes, downcase it and search for the existence of something. Like this where parsed is a hash:
# parsed could be either:
# {error: "Email does not exist"}
# or
# {result: ... }
return true if parsed.dig('error').downcase!.include?('email does not exist') # refactor
I can see dig returns nil in this case. Is there any way I can tell that if statement to exit if nil? Maybe force it to false and exit without adding a lot of ceremony code?
I know I could do something like this but it seems cumbersome:
unless parsed['error'].nil?
return true if parsed.dig('error').downcase!.include?('email does not exist') # refactor
end
parsed.dig('error').to_s.downcase.include?('email does not exist')
to_s converts nil to ''. No need for downcase! because you don't need to mutate the original object and because it returns nil if no changes were made; just use downcase.
Note that your example uses symbolized keys and your code uses stringified keys, so it'll never match:
parsed = {error: "Email does not exist"} # key is symbolized
parsed.dig('error').to_s.downcase.include?('email does not exist') # key is stringified
=> false
parsed = {error: "Email does not exist"} # key is symbolized
parsed.dig(:error).to_s.downcase.include?('email does not exist') # key is symbolized
=> true
Since you're using Rails, you can make your life a little easier with indifferent access. This allows hash keys to be accessed by string or by symbol:
parsed.with_indifferent_access.dig('error').to_s.downcase.include?('email does not exist')
=> true
parsed.with_indifferent_access.dig(:error).to_s.downcase.include?('email does not exist')
=> true
Using this gives you some flexibility.
While going through the Rails guide at http://guides.rubyonrails.org/layouts_and_rendering.html#avoiding-double-render-errors ,
I wrote a test program to test Ruby's && return, and I got this strange behavior:
def test1
puts 'hello' && return
puts 'world'
end
def test2
puts 'hello' and return
puts 'world'
end
This is the result output:
irb(main):028:0> test1
=> nil
irb(main):029:0> test2
hello
world
=> nil
What accounts for the difference?
Check out the difference between and and &&. In the examples you give the method puts is called without parens around it's arguments and the difference in precedence changes how it is parsed.
In test 1 && has higher precedence than the method call. So what's actually happening is puts('hello' && return). Arguments are always evaluated before the methods they're called with -- so we first evaluate 'hello' && return. Since 'hello' is truthy the boolean does not short circuit and return is evaluated. When return we exit the method without doing anything else: so nothing is ever logged and the second line isn't run.
In test 2 and has a lower precedence than the method call. So what happens is puts('hello') and return. The puts method logs what is passed to it and then returns nil. nil is a falsey value so the and expression short circuits and the return expression is never evaluated. We just move to the second line where puts 'world' is run.
I frequently find myself writing Ruby code where I check for the presence of a value and subsequently do something with that value if it is present. E.g.
if some_object.some_attribute.present?
call_something(some_object.some_attribute)
end
I think it would be cool, if it could be written as
some_object.some_attribute.presence { |val| call_something(val) }
=> the return value of call_something
Anyone know if there's such a feature in Ruby or though activesupport?
I opened a pull request for this feature.
You can use a combination of presence and try:
If try is called without arguments it yields the receiver to a given block unless it is nil:
'foo'.presence.try(&:upcase)
#=> "FOO"
' '.presence.try(&:upcase)
#=> nil
nil.presence.try(&:upcase)
#=> nil
You could try
do_thing(object.attribute) if object.attribute
This is usually fine, unless the attribute is a boolean. In which case it will not call if the value is false.
If your attribute can be false, use .nil? instead.
do_thing(object.attribute) unless object.attribute.nil?
Though there is no such functionality out of the box, one could do:
some_object.some_attribute.tap do |attr|
attr.present? && call_smth(attr)
end
On the other hand, Rails provides so many monkeypatches, that one could append one to this circus:
class Object
def presense_with_rails
raise 'Block required' unless block_given?
yield self if self.present? # requires rails
end
def presense_without_rails
raise 'Block required' unless block_given?
skip = case self
when NilClass, FalseClass then true
when String, Array then empty?
else false
end
yield self unless skip
end
end
I want to check weather variable contains a valid number or not.
I can validate correctly for null and blank but can not validate text as a "Integer"...
I tried:
if(params[:paramA].blank? || (params[:paramA].is_a?(Integer)) )
I have also tried is_numeric, is_numeric(string), is_number? and other ways...
but did not get success...
I saw such patch:
class String
def is_number?
true if Float(self) rescue false
end
end
if (params[:paramA].blank? || !params[:paramA].is_number?)
Or without the patch:
if (params[:paramA].blank? || (false if Float(params[:paramA]) rescue true))
It supports 12, -12, 12.12, 1e-3 and so on.
If your parameter is for an ActiveRecord model, then you should probably use validates_numericality_of. Otherwise...
You only want integers, right? How about:
if (params[:paramA].blank? || params[:paramA] !~ /^[+-]?\d+$/)
That is, check whether the parameter consists of an optional + or -, followed by 1 or more digits, and nothing else.
If the thing you want to do is this:
I want to check weather variable contains a valid number or not.
You can get it with regex. See it here
s = 'abc123'
if s =~ /[-.0-9]+/ # Calling String's =~ method.
puts "The String #{s} has a number in it."
else
puts "The String #{s} does not have a number in it."
end
In rails you can use the numeric? method on a String or Integer or Float which does exactly what you need.
123.numeric?
# => true
123.45.numeric?
# => true
"123".numeric?
# => true
"123.45".numeric?
# => true
"a1213".numeric?
# => false
UPDATE
My bad, I had a dirty environment, the above works if mongoid version 3 and above is loaded.
How do you say not to match in Ruby Regex
ex. you do not want to return true if it sees 'error'
/\b(error)\b/i
I know this returns true when it sees error, how do you say 'not' in this case? thanks!
Use the proper Ruby operator:
/\b(error)\b/i !~ someText
I would do something like the following excuse the /error/ pattern not sure exactly what you want to match here
return true unless b =~ /error/
or
return true if b !~ /error/