How to make ruby indicate error before a binary function? - ruby

I have this code that works:
stripped = "00010001"
IO.binwrite("Test.txt", [stripped].pack('B*'))
But if stripped equals to:
stripped = "00013001"
Ruby writes the "binary" anyway. How can I make Ruby give me a mistake and not write it down?

"1000101010".scan(/[^01]/).any?
This simply performs a regex on the string looking for any characters that are not 0 or 1 and returns true if the string has any other characters.

The Integer method of Kernel accepts a base as argument and is strict (by default).
Integer("00011001",2).to_s(16)
# => "19"
Integer("00013001",2).to_s(16)
# => invalid value for Integer(): "00013001" (ArgumentError)

Related

Ruby gsub with string manipulation

I am new to ruby and writing the expression to replace the string between the xml tags by hashing the value inside that.
I did the following to replace with the new password
puts "<password>check1</password>".gsub(/(?<=password\>)[^\/]+(?=\<\/password)/,'New \0')
RESULT: <password>New check1</password> (EXPECTED)
My expectation is to get the result like this (Md5 checksum of the value "New check1")
<password>6aaf125b14c97b307c85fc6e681c410e</password>
I tried it in the following ways and none of them was successful (I have included the required libraries "require 'digest'").
puts "<password>check1</password>".gsub(/(?<=password\>)[^\/]+(?=\<\/password)/,Digest::MD5.hexdigest('\0'))
puts "<password>check1</password>".gsub(/(?<=password\>)[^\/]+(?=\<\/password)/,Digest::MD5.hexdigest '\0')
puts "<password>check1</password>".gsub(/(?<=password\>)[^\/]+(?=\<\/password)/, "Digest::MD5.hexdigest \0")
Any help on this to achieve the expectation is very much appreciated
This will work:
require 'digest'
line = "<other>stuff</other><password>check1</password><more>more</more>"
line.sub(/<password>(?<pwd>[^<]+)<\/password>/, Digest::SHA2.hexdigest(pwd))
=> "<other>stuff</other>8a859fd2a56cc37285bc3e307ef0d9fc1d2ec054ea3c7d0ec0ff547cbfacf8dd<more>more</more>"
Make sure the input is one line at a time, and you'll probably want sub, not gsub
P.S.: agree with Tom Lord's comment.. if your XML is not gargantuan in size, try to use an XML library to parse it... Ox or Nokogiri perhaps?
Different libraries have different advantages.
This is a variant of Tilo's answer.
require 'digest'
line = "<other>stuff</other><password>check1</password><more>more</more>"
r = /(?<=<password>).+?(?=<\/password>)/
line.sub(r) { |pwd| Digest::SHA2.hexdigest(pwd) }
#=> "<other>stuff</other><password>8a859fd2a56cc37285bc3e307ef0d9f
# c1d2ec054ea3c7d0ec0ff547cbfacf8dd</password><more>more</more>"
(I've displayed the returned string on two lines so make it readable without the need for horizontal scrolling.)
The regular expression reads, "match '<password>' in a positive lookbehind ((?<=...)), followed by any number of characters, lazily ('?'), followed by the string '</password>' in a positive lookahead ((?=...)).

Why is `?something` invalid?

?. is a string literal:
?. #=> "."
However, I failed to declare a variable with a name like that:
?some_var = 100 #=> Error
How is?something invalid when ?. is valid?
? cannot describe any string literal; it is valid only for a single character.
Even if ?something were a valid string literal (counter to fact),
?something = ...
will be assignment to a string, which does not make sense. You cannot assign a value to a string.
?a is the same as "a". So it is a value, which belongs on the right hand side of an assignment, not the left hand side. It is not a variable name.
The Syntax exists as a relic from Ruby <=1.9, where it was equivalent to "a".bytes[0] and ?d could be used to shave off one character of code golf. I haven't seen any legitimate use otherwise.

Check if a string contains a character in a unicode range (using Ruby)

I want to create a simple function in Ruby that will check if the given string contains any unicode characters in the ranges such as the following:
U+007B -- U+00BF
U+02B0 -- U+037F
U+2000 -- U+2BFF
How can I accomplish this? Google is coming up blank for me, all things about removing unicode characters or checking if a string contains unicode.
The easiest thing would probably be a regex using String#index, String#match, or even String#[]:
string.index(/[\u007B-\u00BF\u02B0-\u037F\u2000-\u2BFF]/)
string.match(/[\u007B-\u00BF\u02B0-\u037F\u2000-\u2BFF]/)
string[/[\u007B-\u00BF\u02B0-\u037F\u2000-\u2BFF]/]
All three will give you nil (which is falsey) if they don't find the pattern and non-nil (which will be truthy) if they do.
I would do as below:
my_string = "{ How are you ?}"
puts my_string.chars.any? { |chr| ("\u007B".."\u00BF").include?(chr) }
#=> true

How do I retrieve the string value of a letter in an array?

I am trying to retrieve the value of a letter in an array. The array I have is:
a = ["a","b","c","d","e","f","g","h"].
If I want to retrieve a letter's value, the code is:
?a
However, when I tried ?a[5] it gives me 0. Does anyone know why this is the case?
--sorry to clarify I am using 1.8.7 :)
Actually, as of Ruby 1.9. ?a will give you the string "a", where it used to give you the ASCII code for that character. It's just another (limited) string literal mechanism at this point.
If you want a characters value, you need to use the ord method, as in a[5].ord or ?a.ord. ord is documented at http://ruby-doc.org/core-2.0.0/String.html#method-i-ord
The behavior of the ? operator and the String [] method when passed a single Fixnum changed at the same time in Ruby 1.9, with both returning a one-character string where they used to return a Fixnum.
As an aside, I can't find the documentation of the ? operator in the Literals/String section of the same official reference.
That is because of associativity/precedence. ?a[5] is interpreted as (?a)[5], not as ?(a[5]). I suppose you expected the latter, but it actually is the former.
In Ruby 1.8 ?a == 'a'[0]. Info about the ? operator (search for: "Integer and Floating Point Numbers")
Therefore you can get the value for a letter in the array a with:
a[5][0]
Whereas in Ruby > 1.9 use the method ord: a[5].ord

Converting a string a number (exactly as it is represented in it)?

I have the following:
{:department=>{"Pet Supplies"=>{"Birds"=>"16,414", "Cats"=>"243,384",
"Dogs"=>"512,186", "Fish & Aquatic Pets"=>"47,018",
"Horses"=>"14,749", "Insects"=>"359", "Reptiles &
Amphibians"=>"5,794", "Small Animals"=>"19,797"}}}
Now if I use to_i I get say 16. If I do to_f I get something like 16.0 (and as you can see Ruby is considering the , as a . for some reason).
I want the number to be exactly as in the string but as a number instead: "Birds"=>16,414
How to accomplish that?
Just a notice:
If I do to_f I get something like 16.0 (and as you can see Ruby is considering the , as a . for some reason)
Ruby is not treating the , as a . at all. If it would the resulting float would be 16.414 and not 16.0. Ruby is just noticing an extraneous character and decides to ignore ,414.
How to accomplish that?
Well if you want 16,414 to be transformed to 16414 there's nothing as easy as just removing the character:
str = '16,414'
str.delete(',').to_i
# => 16414
In some cultures the , is considered a floating point. In that case, if you want to return 16.414 you can just transform the , into . and convert to Float:
str = '16,414'
str.gsub(/,/, '.').to_f
# => 16.414
Try something like below:
"16,414".gsub(",","_").to_i
# => 16414
or(as #Chris Heald suggested)
"19,797".delete(",").to_i
# => 19797
as you can see Ruby is considering the , as a . for some reason
Yes, it's all quite confusing:
class String
to_i(base=10) → integer
Returns the result of interpreting leading characters in str as an
integer base base (between 2 and 36). Extraneous characters past the
end of a valid number are ignored.
to_f → float
Returns the result of interpreting leading characters in str as a
floating point number. Extraneous characters past the end of a valid
number are ignored.
The ruby docs are public. They are not secret. In fact, you probably have the docs on your computer. Try this:
$ ri String#to_i

Resources