How to check if an IP address (or range) is valid - ruby

I've run across several posts to check if whether or not an IP address is valid using various gems, but none them seem to have the capability of determining if whether or not the CIDR format is being used.
For example:
irb(main):057:0> "192.168.1.1" =~ Resolv::IPv4::Regex ? true : false #=> true
=> true
irb(main):058:0> "192.168.1.1/30" =~ Resolv::IPv4::Regex ? true : false #=> true
=> false
irb(main):059:0>
and
irb(main):059:0> IPAddress.valid? "192.168.1.1"
=> true
irb(main):060:0> IPAddress.valid? "192.168.1.1/32"
=> false
are two of the most common ways I've seen this being used. How do I incorporate CIDR notation as well in these validation checks?

You could use the parse method if the ipaddress gem (https://github.com/ipaddress-gem/ipaddress)
Parsing a valid address:
3.0.0 :005 > x = IPAddress.parse "192.168.1.1/32"
=> #<IPAddress::IPv4:0x00007f92d684f010 #address="192.168.1.1", #prefix=32, #octets=[192, 168, 1, 1], #u32=3232235777>
Parsing an invalid address raises:
3.0.0 :006 > x = IPAddress.parse "192.168.1.1.1/32"
Traceback (most recent call last):
...

Related

Check if a string contains only digits in ruby

I have a string which is passed as a parameter to a function. Here, I want to check if the string contains only numbers. So I had a check like below:
def check_string(string)
result = false
if string.to_i.to_s.eql? string
result = true
end
result
end
But the problem arises when a string starts with 0. In that case, a false is returned.
check_string('123') #=> true
check_string('0123') #=> false
How can I solve this issue?
You can try the following
def check_string(string)
string.scan(/\D/).empty?
end
It would be truthy if string contains only digits or if it is an empty string. Otherwise returns false.
A number can be negative, or a float. So if these are allowed, consider this solution:
def is_numberic?(str)
str == "#{str.to_f}" || str == "#{str.to_i}"
end
some input which evaluate to true
pry(main)> is_numberic? '5'
=> true
pry(main)> is_numberic? '58127721'
=> true
pry(main)> is_numberic? '58127721.737673'
=> true
pry(main)> is_numberic? '0'
=> true
pry(main)> is_numberic? '1818'
=> true
pry(main)> is_numberic? '0.1'
=> true
pry(main)> is_numberic? '0.0'
=> true
pry(main)> is_numberic? '11.29'
=> true
pry(main)> is_numberic? '-0.12'
=> true
pry(main)> is_numberic? '-29'
=> true
the input which evaluate to false
pry(main)> is_numberic? '10 years'
=> false
pry(main)> is_numberic? '01'
=> false
pry(main)> is_numberic? '00'
=> false
pry(main)> is_numberic? '0.10'
=> false
pry(main)> is_numberic? ''
=> false
As you can see, there're several cases which probably should be supported, eg '0.10', but are not. In this case, the permitted input is '0.1'.
def check_string(str)
str !~ /\D/
end
check_string '123'
#=> true
check_string ''
#=> true
check_string '1a2'
#=> false
this is my proposition for detecting if it's a float number
def check(string)
scan = string.scan(/\D/)
scan.size == 0 || (scan.size == 1 && scan.first == ".") # or "," depend on your separator
end
example of use:
check("123") => true
check("12.3") => true
check("12e3") => false
check("12.3.2") => false
EDIT: 2023
After some years i see this is the most compact solution:
def check_string(str)
str.scan(/\D/).empty?
end
You can use Regexp for it:
def check_string(string)
raise 'Empty string passed' if string.empty?
/\A\d+\z/ === string
end
check_string '123'
#=> true
check_string '0123'
#=> true
check_string '0'
#=> true
We can also use the "match" function to do this.
"1234".match(/\D/)
#=> nil
"1234foo".match(/\D/)
#=> #<MatchData "f">
match (String) - APIdock
I think we should use the regex to find this.
it will work for the below scenarios
"3.0"
"av3"
"3"
is_numeric = false if option.option.match?(/[^0-9.]/)
If anyone is searching for another way to determine if string is numeric -> is to use "is_a? Numeric". Is_a? reference documentation
"namaste".is_a? Numeric
=> false
6.is_a? Numeric
=> true
str1 = "foo"
str2 = 9
str1.is_a? Numeric
=> false
str2.is_a? Numeric
=> true
You can also use:
7.is_a?(Numeric)
=> true
"too".is_a?(Numeric)
=> false
Basically it's determining if a class is a type of class object. I just found this and thought I would share.

Ruby variable value reassigning logic

So I tried searching with different keywords but either I'm a bad search-operator or It's too simple of a problem. Either way my problem is that I can't get my head around this logic in Ruby.
x = 5
x = x + 1
So if I understood it correctly x becomes 6. Why is that? if you "reassign" the value literally doesn't it become "x + 1" without having anything to do with the first line.
Thanks.
Operators are applied in order of their precedence.
It's not that the right side is (always) evaluated first, it's that addition has higher precedence than assignment. Run irb to test.
$ irb
2.2.0 :001 > x # => the variable 'x' doesn't yet exist.
NameError: undefined local variable or method `x' for main:Object
from (irb):1
from /home/mike/.rvm/rubies/ruby-2.2.0/bin/irb:11:in `'
2.2.0 :002 > x = 5 # => Assign x the value 5.
=> 5 # => Evaluating the expression 'x = 5' returns 5
2.2.0 :003 > x # => and the value of 'x' is 5.
=> 5
2.2.0 :004 > x = x + 1 # => Addition has higher precedence than
# => assignment. Ruby evaluates 'x + 1', then
# => assigns the result to 'x', and finally
# => returns the result.
=> 6
2.2.0 :005 > x # => 'x' has the same value as the previous
# => result.
=> 6
2.2.0 :006 > x + 1 # => This expression returns the value 7.
=> 7
2.2.0 :007 > x # => But without the assignment operator (=),
=> 6 # => the value of 'x' didn't change.
Why is this important? Because operator precedence doesn't always work the way you think it ought to.
$ irb
2.2.0 :001 > true and false # => That makes sense.
=> false
2.2.0 :002 > x = true and false # => That *seems* to make sense, but
=> false
2.2.0 :003 > x # => 'x' has the value true, because
=> true # => assignment has higher
# => precedence than Boolean 'and'.
2.2.0 :004 > x = (true and false)
=> false
2.2.0 :005 > x
=> false
2.2.0 :006 >
Most people expect the expression x = true and false to be equivalent to x = (true and false), because they expect Ruby to always evaluate the right side first. But Ruby doesn't do that. It evaluates assignment (=) before Boolean and. So the expression x = true and false is actually equivalent to (x = true) and false.
Ruby's precedence table on SO
The right side is evaluated first
Ruby itself will give you an object_id for each of them and you could possibly use this to identify all your objects. But there’s a little gotcha:
x = 'matz'
=> "matz"
y = 'matz'
=> "matz"
[ x.object_id, y.object_id ]
=> [2164843460, 2134818480]
So Ruby interpreter identify the object_id and assign value in that memory place
interpreter starts with the operator having the highest precedence

Ruby regular expression method !~

I don't remember where I learned the !~ method of the String class. However I know it compares a string to a regex and check whether the string not match the regex. See my below example.
C:\>irb
irb(main):001:0> "abba" =~ /(\w)(\w)\2\1/i
=> 0
irb(main):002:0> "xxxx" =~ /(\w)(\w)\2\1/i
=> 0
irb(main):003:0> "asdf" =~ /(\w)(\w)\2\1/i
=> nil
irb(main):004:0> "asdf" !~ /(\w)(\w)\2\1/i
=> true
irb(main):005:0> "asdf" !~ /asdf/i
=> false
irb(main):006:0>
I want to find more information of the method but I can't find it in the rdoc of both String and Regexp. Anyone can give some help?
Thanks.
Since this is the method you can find it here in the Methods filter.
I've found this description.
obj !~ other → true or false
Returns true if two objects do not match (using the =~ method), otherwise false.

ruby way of checking if an object is in an array

I come from the Java world so I was shocked to discover that arrays (http://ruby-doc.org/core/classes/Array.html) does not hava a method contains(object) returning bool.
What is the good way - the Ruby way - of doing that ?
array.include?(obj) → true or false
Returns true if the given object is present in self (that is, if any object == anObject), false otherwise.
a = [ "a", "b", "c" ]
a.include?("b") #=> true
a.include?("z") #=> false
This, from the Array class documentation:
[1,2,3].include? 2
=> true
ruby-1.9.2-p0 > [1,2,3].include? 3
=> true
ruby-1.9.2-p0 > [1,2,3].include? 33
=> false
You can do this:
Array.index("ITEM")
if the result is != de nil the element exists.
Regards.

Ruby equivalent of Perl Data::Dumper

I am learning Ruby & Perl has this very convenient module called Data::Dumper, which allows you to recursively analyze a data structure (like hash) & allow you to print it. This is very useful while debugging. Is there some thing similar for Ruby?
Look into pp
example:
require 'pp'
x = { :a => [1,2,3, {:foo => bar}]}
pp x
there is also the inspect method which also works quite nicely
x = { :a => [1,2,3, {:foo => bar}]}
puts x.inspect
I normally use a YAML dump if I need to quickly check something.
In irb the syntax is simply y obj_to_inspect. In a normal Ruby app, you may need to add a require 'YAML' to the file, not sure.
Here is an example in irb:
>> my_hash = {:array => [0,2,5,6], :sub_hash => {:a => 1, :b => 2}, :visible => true}
=> {:sub_hash=>{:b=>2, :a=>1}, :visible=>true, :array=>[0, 2, 5, 6]}
>> y my_hash # <----- THE IMPORTANT LINE
---
:sub_hash:
:b: 2
:a: 1
:visible: true
:array:
- 0
- 2
- 5
- 6
=> nil
>>
The final => nil just means the method didn't return anything. It has nothing to do with your data structure.
you can use Marshal, amarshal, YAML

Resources