This question already has answers here:
Why Integer("09") throwing exception in ruby while Integer("07") works pretty well?
(2 answers)
Closed 1 year ago.
Why, in ruby 2.7.4p191 (2021-07-07 revision a21a3b7d23) [x86_64-darwin20], this is happening?
irb(main):001:0> Integer("01")
=> 1
irb(main):002:0> Integer("02")
=> 2
irb(main):003:0> Integer("03")
=> 3
irb(main):004:0> Integer("04")
=> 4
irb(main):005:0> Integer("05")
=> 5
irb(main):006:0> Integer("06")
=> 6
irb(main):007:0> Integer("07")
=> 7
irb(main):008:0> Integer("08")
Traceback (most recent call last):
5: from /Users/sig/.rbenv/versions/2.7.4/bin/irb:23:in `<main>'
4: from /Users/sig/.rbenv/versions/2.7.4/bin/irb:23:in `load'
3: from /Users/sig/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/irb-1.2.6/exe/irb:11:in `<top (required)>'
2: from (irb):8
1: from (irb):8:in `Integer'
ArgumentError (invalid value for Integer(): "08")
irb(main):009:0> Integer("09")
Traceback (most recent call last):
6: from /Users/sig/.rbenv/versions/2.7.4/bin/irb:23:in `<main>'
5: from /Users/sig/.rbenv/versions/2.7.4/bin/irb:23:in `load'
4: from /Users/sig/.rbenv/versions/2.7.4/lib/ruby/gems/2.7.0/gems/irb-1.2.6/exe/irb:11:in `<top (required)>'
3: from (irb):8
2: from (irb):9:in `rescue in irb_binding'
1: from (irb):9:in `Integer'
ArgumentError (invalid value for Integer(): "09")
A leading zero indicates an octal (radix 8) integer.
07 - valid octal integer seven
08 - invalid octal integer, the least significant digit is invalid
Instead, you probably want to specify decimal (radix 10) integers.
7 - valid decimal integer seven
8 - valid decimal integer eight
Related
Time.local vs Time.new
Both method return Time object.
irb(main):005:0> Time.new(2020,1,1).class
=> Time
irb(main):006:0> Time.local(2020, 1, 1).class
=> Time
irb(main):007:0> Time.local(2020, 1, 1)
=> 2020-01-01 00:00:00 +0900
irb(main):008:0> Time.new(2020,1,1)
=> 2020-01-01 00:00:00 +0900
irb(main):009:0>
I don't know when should I use each method.
Time.local vs Time.new
Time.local will give error if no argument is given, whereas Time.new is initialized to the current system time if no argument is given.
Time.local will always return values in the local time zone. Time.new accepts the timezone parameter & if given returns the value in in the respective time zone.
Check this
2.5.1 :018 > Time.new.zone
=> "IST"
2.5.1 :019 > Time.new
=> 2020-11-18 19:50:30 +0530
2.5.1 :020 > Time.local
Traceback (most recent call last):
3: from /Users/salilgaikwad/.rvm/rubies/ruby-2.5.1/bin/irb:11:in `<main>'
2: from (irb):20
1: from (irb):20:in `local'
ArgumentError (wrong number of arguments (given 0, expected 1..8))
2.5.1 :021 > Time.new(2020,11,18,15,25,0, "+09:00")
=> 2020-11-18 15:25:00 +0900
2.5.1 :022 > Time.local(2020,11,18,15,25,0, "+09:00")
=> 2020-11-18 15:25:00 +0530
It looks like you must pass arguments to #local,r whereas you don't need to pass arguments to #new and it would return current time.
I'm writing a test for a method that tests the following method:
def update rule_code, updated_rule
list.select{ |rule|
if rule[0] == rule_code
rule[1] = updated_rule
end
}
end
The test looks like:
describe "#update" do
it "updates a rule when given the rulecode and rule updates" do
item_rule = double( {rule_type: "item", item_code: 1, number_of_items: 2, new_item_price: 8.50} )
updated_rule = double( {rule_type: "item", item_code: 1, number_of_items: 4, new_item_price: 7.50} )
rule_code = 1
rules.add item_rule
expect{rules.update(rule_code, updated_rule)}.to change{rules.list[rule_code]}.from(item_rule).to(updated_rule)
end
end
I'm getting the following error:
1) Promotional_Rules#update updates a rule when given the rulecode and rule updates
Failure/Error: rule[1] = updated_rule
NoMethodError:
undefined method `[]=' for 1:Fixnum
# ./lib/Promotional_Rules.rb:21:in `block in update'
# ./lib/Promotional_Rules.rb:19:in `select'
# ./lib/Promotional_Rules.rb:19:in `update'
# ./spec/promotional_rules_spec.rb:39:in `block (4 levels) in <top (required)>'
# ./spec/promotional_rules_spec.rb:39:in `block (3 levels) in <top (required)>'
The test result isn't the issue as I am sure the final line of my test isn't correct. I am trying to test that in the following hash:
list = {1: {rule_type: "item", item_code: 1, number_of_items: 2, new_item_price: 8.50}, 2: {rule_type: "item", item_code: 2, number_of_items: 6, new_item_price: 9.50}
If I search for the original key "1" I can then update it with its corresponding pair. I also realize my method isn't correct either hence the test failure.
I was wondering if there is a Ruby equivalent of JavaScript's fromCharCode function. What it does is converting Unicode values into characters.
Here an example of its return value in JavaScript:
String.fromCharCode(72,69,76,76,79)
#=> HELLO
Is there an equivalent for that in Ruby?
Use Integer#chr:
72.chr
# => "H"
[72,69,76,76,79].map{|i| i.chr }.join
# => "HELLO"
[72,69,76,76,79].map(&:chr).join
# => "HELLO"
UPDATE
Without parameters chr only handles 8-bit ASCII characters, you have to pass the parameter Encoding::UTF_8 to chr to handle Unicode characters.
512.chr
RangeError: 512 out of char range
from (irb):8:in `chr'
from (irb):8
from /usr/bin/irb:12:in `<main>'
512.chr(Encoding::UTF_8)
# => "Ȁ"
[512,513].map{|i| i.chr(Encoding::UTF_8)}.join
# => "Ȁȁ"
I am trying to use the Ruby Sequel gem for DB operations.
I am stuck for incrementing and decrementing values.
The doc says that this should work, even though it seems very strange for me to be able to add a number and a symbol.
2.0.0-p247 :019 > require 'sequel'
=> true
2.0.0-p247 :020 > s = Sequel.connect('sqlite://db.sqlite')
=> #<Sequel::SQLite::Database: "sqlite://db.sqlite">
2.0.0-p247 :021 > s[:query_volume].update_sql(:queries => 3)
=> "UPDATE `query_volume` SET `queries` = 3"
2.0.0-p247 :022 > s[:query_volume].update_sql(:queries => :queries + 3)
NoMethodError: undefined method `+' for :queries:Symbol
from (irb):21
from /Users/avandra/.rvm/rubies/ruby-2.0.0-p247/bin/irb:16:in `<main>'
But as you can see it gives undefined method on the queries symbol. Which is kindof concurs with why it was strange for me.
I tried using curly braces, but that gives another error:
2.0.0-p247 :023 > s[:query_volume].update_sql{:queries => :queries + 3}
SyntaxError: (irb):23: syntax error, unexpected =>, expecting '}'
s[:query_volume].update_sql{:queries => :queries + 3}
^
from /Users/avandra/.rvm/rubies/ruby-2.0.0-p247/bin/irb:16:in `<main>'
And using
2.0.0-p247 :033 > s[:query_volume].update_sql{queries = queries + 3}
=> "UPDATE `query_volume` SET "
just gives a badly formatted SQL...
Could anyone shed some light on how this can be done?
You should use Sequel.expr for that:
s[:query_volume].update_sql(:queries => Sequel.expr(3) + :queries)
On this page http://swtch.com/~rsc/regexp/regexp3.html it says that RE2 supports named expressions.
RE2 supports Python-style named captures (?P<name>expr), but not the
alternate syntaxes (?<name>expr) and (?'name'expr) used by .NET and
Perl.
ruby-1.9.2-p180 :003 > r = RE2::Regexp.compile("(?P<foo>.+) bla")
#=> #<RE2::Regexp /(?P<foo>.+) bla/>
ruby-1.9.2-p180 :006 > r = r.match("lalal bla")
#=> #<RE2::MatchData "lalal bla" 1:"lalal">
ruby-1.9.2-p180 :009 > r[1] #=> "lalal"
ruby-1.9.2-p180 :010 > r[:foo]
TypeError: can't convert Symbol into Integer
ruby-1.9.2-p180 :011 > r["foo"]
TypeError: can't convert String into Integer
But I'm not able to access the match with the name, so it seems like a useless implementation. Am I missing something?
Looking at your code output, it seems that you are using the Ruby re2 gem which I maintain.
As of the latest release (0.2.0), the gem does not support the underlying C++ re2 library's named capturing groups. The error you are seeing is due to the fact that any non-integer argument passed to MatchData#[] will simply be forwarded onto the default Array#[]. You can confirm this in an irb session like so:
irb(main):001:0> a = [1, 2, 3]
=> [1, 2, 3]
irb(main):002:0> a["bob"]
TypeError: can't convert String into Integer
from (irb):2:in `[]'
from (irb):2
from /Users/mudge/.rbenv/versions/1.9.2-p290/bin/irb:12:in `<main>'
irb(main):003:0> a[:bob]
TypeError: can't convert Symbol into Integer
from (irb):3:in `[]'
from (irb):3
from /Users/mudge/.rbenv/versions/1.9.2-p290/bin/irb:12:in `<main>'
I will endeavour to add the ability to reference captures by name as soon as possible and update this answer once a release has been made.
Update: I just released version 0.3.0 which now supports named groups like so:
irb(main):001:0> r = RE2::Regexp.compile("(?P<foo>.+) bla")
=> #<RE2::Regexp /(?P<foo>.+) bla/>
irb(main):002:0> r = r.match("lalal bla")
=> #<RE2::MatchData "lalal bla" 1:"lalal">
irb(main):003:0> r[1]
=> "lalal"
irb(main):004:0> r[:foo]
=> "lalal"
irb(main):005:0> r["foo"]
=> "lalal"