Using regex in Ruby if condition - ruby-on-rails

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

How to check and return string or return false and exit if statement

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.

Ruby: "&& return" vs "and return"

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.

Do something if value is present

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

Check string is a valid number or not in ruby

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.

Ruby Regex How to specify not to match

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/

Resources