Accidental expression evaluation in ruby - ruby-on-rails

Why this expression evaluating to 13 ?.
I accidentally evaluated this expression (1_2).next instead of (1+2).next which o/p 4 as result.
=> (1_2).next
=> 13
Please let me know how this is, as i m new to Ruby

Ruby allows you to use _ to break up long numbers, for example
123456789 == 123_456_789
but the latter is a little easier to read, so your code is the same as 12.next

1_2 is the same as 12. 12.next is 13. Underscores in numbers are ignored, you can use them for readability. E.g. 1000_000_000 is one billion.

Related

How to remove from string before __

I am building a Rails 5.2 app.
In this app I got outputs from different suppliers (I am building a webshop).
The name of the shipping provider is in this format:
dhl_freight__233433
It could also be in this format:
postal__US-320202
How can I remove all that is before (and including) the __ so all that remains are the things after the ___ like for example 233433.
Perhaps some sort of RegEx.
A very simple approach would be to use String#split and then pick the second part that is the last part in this example:
"dhl_freight__233433".split('__').last
#=> "233433"
"postal__US-320202".split('__').last
#=> "US-320202"
You can use a very simple Regexp and a ask the resulting MatchData for the post_match part:
p "dhl_freight__233433".match(/__/).post_match
# another (magic) way to acces the post_match part:
p $'
Postscript: Learnt something from this question myself: you don't even have to use a RegExp for this to work. Just "asddfg__qwer".match("__").post_match does the trick (it does the conversion to regexp for you)
r = /[^_]+\z/
"dhl_freight__233433"[r] #=> "233433"
"postal__US-320202"[r] #=> "US-320202"
The regular expression matches one or more characters other than an underscore, followed by the end of the string (\z). The ^ at the beginning of the character class reads, "other than any of the characters that follow".
See String#[].
This assumes that the last underscore is preceded by an underscore. If the last underscore is not preceded by an underscore, in which case there should be no match, add a positive lookbehind:
r = /(?<=__[^_]+\z/
This requires the match to be preceded by two underscores.
There are many ruby ways to extract numbers from string. I hope you're trying to fetch numbers out of a string. Here are some of the ways to do so.
Ref- http://www.ruby-forum.com/topic/125709
line.delete("^0-9")
line.scan(/\d/).join('')
line.tr("^0-9", '')
In the above delete is the fastest to trim numbers out of strings.
All of above extracts numbers from string and joins them. If a string is like this "String-with-67829___numbers-09764" outut would be like this "6782909764"
In case if you want the numbers split like this ["67829", "09764"]
line.split(/[^\d]/).reject { |c| c.empty? }
Hope these answers help you! Happy coding :-)

How can I catch a US phone number with +1 area code regex

I have the following requirement.
I need to validate with Rails that a phone number begins with +1 and is met with exactly 10 digits after this? So far, I have this regex expression.
^+1\d{10}
This is not working and I'm having a bit of trouble trying to tweak this to match exactly what I need. Does anyone have any ideas the validation has to catch this exactly.
+19564321234
etc. Help would be appreciated. Thank you.
You have two problems with your regular expression:
You have not escaped the plus sign, so it reads, "match the beginning of a line, followed by one or more (+) zero-width characters, followed by 10 digits"
You have omitted an end-of-string anchor, so \d{10} will match a string of 10 or more digits
You need to write:
r = /\A\+\d{10}\z/
"+1234567890".match? r #=> true
"1234567890".match? r #=> false
"+1234567890123".match? r #=> false
I've used the beginning-of-string anchor, \A, rather than the beginning-of-line anchor ^. The latter would be in problem only in some extreme cases, such as:
"dog\n+1234567890".match? /^\+\d{10}\z/ #=> true
Start your engine!. To see it tested against several strings one must change the anchors to ^ and $ and add the multiline (/m) modifier.

Rails strip all except numbers commas and decimal points

Hi I've been struggling with this for the last hour and am no closer. How exactly do I strip everything except numbers, commas and decimal points from a rails string? The closest I have so far is:-
rate = rate.gsub!(/[^0-9]/i, '')
This strips everything but the numbers. When I try add commas to the expression, everything is getting stripped. I got the aboves from somewhere else and as far as I can gather:
^ = not
Everything to the left of the comma gets replaced by what's in the '' on the right
No idea what the /i does
I'm very new to gsub. Does anyone know of a good tutorial on building expressions?
Thanks
Try:
rate = rate.gsub(/[^0-9,\.]/, '')
Basically, you know the ^ means not when inside the character class brackets [] which you are using, and then you can just add the comma to the list. The decimal needs to be escaped with a backslash because in regular expressions they are a special character that means "match anything".
Also, be aware of whether you are using gsub or gsub!
gsub! has the bang, so it edits the instance of the string you're passing in, rather than returning another one.
So if using gsub! it would be:
rate.gsub!(/[^0-9,\.]/, '')
And rate would be altered.
If you do not want to alter the original variable, then you can use the version without the bang (and assign it to a different var):
cleaned_rate = rate.gsub!(/[^0-9,\.]/, '')
I'd just google for tutorials. I haven't used one. Regexes are a LOT of time and trial and error (and table-flipping).
This is a cool tool to use with a mini cheat-sheet on it for ruby that allows you to quickly edit and test your expression:
http://rubular.com/
You can just add the comma and period in the square-bracketed expression:
rate.gsub(/[^0-9,.]/, '')
You don't need the i for case-insensitivity for numbers and symbols.
There's lots of info on regular expressions, regex, etc. Maybe search for those instead of gsub.
You can use this:
rate = rate.gsub!(/[^0-9\.\,]/g,'')
Also check this out to learn more about regular expressions:
http://www.regexr.com/

Retaining the pattern characters while splitting via Regex, Ruby

I have the following string
str="HelloWorld How areYou I AmFine"
I want this string into the following array
["Hello","World How are","You I Am", "Fine"]
I have been using the following regex, it splits correctly but it also omits the matching pattern, i also want to retain that pattern.
What i get is
str.split(/[a-z][A-Z]/)
=> ["Hell", "orld How ar", "ou I A", "ine"]
It omitts the matching pattern.
Can any one help me out how to retain these characters as well in the resulting array
In Ruby 1.9 you can use positive lookahead and positive lookbehind (lookahead and lookbehind regex constructs are also called zero-width assertions). They match characters, but then give up the match and only return the result, thus you won't loose your border characters:
str.split /(?<=[a-z])(?=[A-Z])/
=> ["Hello", "World How are", "You I Am", "Fine"]
Ruby 1.8 does not support lookahead/lookbehind constructs. I recommend to use ruby 1.9 if possible.
If you are forced to use ruby 1.8.7, I think regex won't help you and the best solution I can think of is to build a simple state machine: iterate over each character in your original string and build first string until you encounter border condition. Then build second string etc.
Three answers so far, each with a limitation: one is rails-only and breaks with underscore in original string, another is ruby 1.9 only, the third always has a potential error with its special character. I really liked the split on zero-width assertion answer from #Alex Kliuchnikau, but the OP needs ruby 1.8 which doesn't support lookbehind. There's an answer that uses only zero-width lookahead and works fine in 1.8 and 1.9 using String#scan instead of #split.
str.scan /.*?[a-z](?=[A-Z]|$)/
=> ["Hello", "World How are", "You I Am", "Fine"]
I think this will do the job for you
str.underscore.split(/_/).each do |s|
s.capitalize!
end

Does Ruby/Rails have a ++ equivalent?

I guess I just got used to saying things like:
x++
in PHP and Java land. But when I tried this in my Rails code it had a fit:
compile error
/users/gshankar/projects/naplan/app/views/answers/new.html.haml:19: syntax error, unexpected ';'
/users/gshankar/projects/naplan/app/views/answers/new.html.haml:23: syntax error, unexpected kENSURE, expecting kEND
...}\n", 0, false);_erbout;ensure;#haml_buffer = #haml_buffer.u...
^
/users/gshankar/projects/naplan/app/views/answers/new.html.haml:26: syntax error, unexpected $end, expecting kEND
I googled around a bit for Ruby/Rails operators for a reference to ++ but couldn't find anything. For a language which focuses on writing less I find it a bit strange that there wouldn't be a ++ equivalent. Am I missing something?
Try this:
x += 1
x+=1 is the best you can do in Ruby.
For a detailed explanation, see Why doesn't Ruby support i++ or i--​ (increment/decrement operators)?
While as other answers point out x += 1 and x -= 1 is one way to do this. The closest Ruby gets to the --/++ operators are the prev()/next() (next has an alias of succ()) methods which return the previous/next items in sequence and are available on unambiguous strictly ordered classes (like String).
x = 4 # => 4
x.succ # => 5
x.prev # => 3
y = 'ABC' # => 'ABC'
y.succ # => 'ABD'
y.prev # => 'ABB'
Unfortunately, none of these implicitly do assignment which is what the original question was asking about. igul222's answer links to a post from Ruby's creator explaining why this is not possible.
Ruby has very powerful collection processing capabilities that eliminate most needs for these kinds of assignments. In all but the most complex alogrithms, which involve processing multiple collections at different rates in parallel. You should be asking yourself why you need increment/decrement. Because the Ruby way to do operations where increment and decrement operators are commonly used is with an iterator.
Such as each_with_index which executes a given block for each element/index pair in the array.
For example, this code will iterate through an array outputting the string representation fo each element and the parity of its index.
array = ["first", "second", "third","fourth","last"]
array.each_with_index do |object,index|
puts index % 2 ? "even" : "odd"
puts object.to_s
end
Edit: Removed Fixnum extension providing postfix increment because it doesn't work. Upon closer inspection there's nothing stopping you from adding it, but it would involve writing your feature in C, and a recompile.
Edit 2022: Added comment about prev/next/succ functions which are closer in behaviour to the decrement/increment function of --/++ operators
You have to use x+=1 instead.
http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Operators

Resources