Date class misbehaves in Ruby 2.0 - ruby

Ruby version: ruby 2.0.0p247 (2013-06-27) [x64-mingw32]
Why does below code able to create Date object but unable to invoke a valid method on it?
Code version 1
p d = Date.new # Works fine - Prints - #<Date:0x000000027aa628>
p Date.gregorian_leap?(2016) # undefined method `gregorian_leap?' for Date:Class (NoMethodError)
Code version 2 Above code works fine if we add require statement
require 'date'
p d = Date.new # Prints #<Date: -4712-01-01 ((0j,0s,0n),+0s,2299161j)>
p Date.gregorian_leap?(2016) # Prints true
Which Date class is getting instantiated in version 1 above? Does Ruby have concept of fully qualified class name which we can inspect to find the difference in two cases?
Ruby version: ruby 2.2.2p95 (2015-04-13 revision 50295) [x64-mingw32]
In Ruby 2.2, Date.new fails early - does not misbehave like Ruby 2.0 did
p d = Date.new # uninitialized constant Date (NameError)
p Date.gregorian_leap?(2016) # did not reach here, previous line errored out

As pointed by Marek Lipka (in comments section),
It's because Ruby 2.0 had an empty Date class for compatibility
reasons.
Reference: bugs.ruby-lang.org/issues/9890

Related

Where is SimpleDelegator in Ruby 2.7?

I have been using the SimpleDelegator class for various things. But I noticed, Ruby 2.7 (ArchLinux x86_64) doesn't come with the SimpleDelegator class (no Delegator either).
My program:
#!/usr/bin/ruby -w
class OutputDecorator < SimpleDelegator
def puts(*args)
STDOUT.write "Hello #{args.join}... It's Ruby #{RUBY_VERSION} #{RUBY_PLATFORM}\n"
end
end
$stdout = OutputDecorator.new($stdout)
$stdout.puts('Sourav')
$stdout = $stdout.__getobj__
$stdout.puts('Sourav')
Running with:
Ruby 2.4.6:
> ~/.rvm/rubies/ruby-2.4.6/bin/ruby p.rb
Hello Sourav... It's Ruby 2.4.6 x86_64-linux
Sourav
Ruby 2.5.5:
> ~/.rvm/rubies/ruby-2.5.5/bin/ruby p.rb
Hello Sourav... It's Ruby 2.5.5 x86_64-linux
Sourav
Ruby 2.6.3:
> ~/.rvm/rubies/ruby-2.6.3/bin/ruby p.rb
Hello Sourav... It's Ruby 2.6.3 x86_64-linux
Sourav
Ruby 2.7.0:
> ruby p.rb
Traceback (most recent call last):
p.rb:2:in `<main>': uninitialized constant SimpleDelegator (NameError)
Is there any new alternatives to SimpleDelegator in Ruby 2.7?
The Delegator and SimpleDelegator classes aren't core classes like Array or Mutex. They're part of the delegate standard library which needs to be loaded first: require 'delegate'.
It happened to work in older Ruby versions as they came with an older RubyGems version by default. RubyGems is automatically loaded since Ruby 1.9 and until 3.1.0 that meant delegate was loaded indirectly. Updating RubyGems or running ruby with --disable=gems should cause the exact same issue with Ruby <= 2.6 too. irb also loads several standard libraries: delegate but also timeout and many more.
Programming languages with a similar mechanism like C++ also have this issue: instead of load/require there's #include, including a standard library header might include another one, then a newer version might not include the other header anymore and user code relying on the old behavior fails to compile.

Ruby 2.4 Enumerable#sum breaks in Rails 5.1

In Rails 5.1.4 using Ruby 2.3.5, I get this behavior:
>> [].sum
#> nil
I'd like to upgrade to Ruby 2.4, where Enumerable#sum is implemented natively. Testing this in IRB using Ruby 2.4.2, I get this result:
>> [].sum
#> 0
That's OK, and I can handle the different result. But going back to the Rails console in Rails 5.1.4 using Ruby 2.4.2, I get this:
>> [].sum
#> NoMethodError: undefined method `each' for nil:NilClass
However, in a newly created Rails 5.1.4 project, I don't get this error. What's going on here?
Looking at the source for the Active Support enumerable extensions it definitely seems like something odd is going on because you shouldn't have been getting the behaviour you described for Rails 5.1.4 using Ruby 2.3.5 i.e. you should have been getting 0 not nil there too.
Active Support's Array#sum checks if Ruby's own sum can be used by checking first.is_a?(Numeric). This will be false for an empty array so the call to super will call Enumerable#sum and both implementations of that have a default of 0.
Try [].method(:sum).source_location in the Rails console of your existing project to see if Array#sum is being overridden somewhere.
if that returns the expected line from active_support/c‌​ore_ext/enumerable.r‌​b then the next step will be to check [].method(:sum).super_method.source_location and see if a customised Enumerable#sum is the culprit.
I think that your application have some overhidden on sum method. Look the example below with 2 new applications using the 2 different versions of ruby
/testapp# ruby --version
ruby 2.4.2p198 (2017-09-14 revision 59899) [x86_64-linux]
/testapp# rails --version
Rails 5.1.4
/testapp# rails c
irb(main):001:0> [].sum
=> 0
and the other version
/testapp# ruby --version
ruby 2.3.5p376 (2017-09-14 revision 59905) [x86_64-linux]
/testapp# rails --version
Rails 5.1.4
/testapp# rails c
irb(main):001:0> [].sum
=> 0

What is the purpose of []= method on nil [duplicate]

This question already has an answer here:
In Ruby, why does nil[1]=1 evaluate to nil?
(1 answer)
Closed 6 years ago.
Since ruby 2.3.0, you can call []= method on nil. I don't understand the purpose of this method.
For instance:
nil[1] = 1
# or
nil['foo'] = 'bar'
but [] method does not exist:
nil[1]
# => NoMethodError: undefined method `[]' for nil:NilClass
The ruby 2.3.0 changelog does not mention that changes, although it seems close to the safe navigation operator.
What is the purpose of this operator?
That seems to be actually a bug in 2.3.0 - https://bugs.ruby-lang.org/issues/11976
It does not evaluate the arguments:
nil[undefined_index_variable] = raise "Fooo!" # => nil
That method isn't documented in Ruby 2.3.0 and I cannot reproduce this behavior in Ruby 2.3.1 (both examples raise NoMethodError: undefined method '[]=' for nil:NilClass).
Furthermore I reinstalled 2.3.0 and was only partly able to reproduce your examples:
$ rbenv install 2.3.0
Downloading ruby-2.3.0.tar.bz2...
-> https://cache.ruby-lang.org/pub/ruby/2.3/ruby-2.3.0.tar.bz2
Installing ruby-2.3.0...
Installed ruby-2.3.0 to /Users/spickermann/.rbenv/versions/2.3.0
$ rbenv shell 2.3.0
$ ruby -v
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin15]
$ irb
irb > RUBY_VERSION
irb => "2.3.0"
irb > nil[1] = 1
irb => nil
irb > nil['foo'] = 'bar'
NoMethodError: undefined method `[]=' for nil:NilClass
from (irb):3
from /Users/spickermann/.rbenv/versions/2.3.0/bin/irb:11:in `<main>'
It seems like NilClass#[]= doesn't work properly in Ruby 2.3.0. Since it was completely removed in 2.3.1, I guess that this method or this behavior was added by accident.
Update: Cary Swoveland pointed out in a comment on another question that this behavior was a bug and was fixed in later versions (see: https://bugs.ruby-lang.org/issues/11976).

Ruby - syntax error, unexpected tLABEL

I am getting syntax error, unexpected tLABEL in below Ruby code. The error description is pointing to ':' after 'timeout'.
def self.run(*args, timeout: nil, environment: {})
# ...
end
I have no knowledge of Ruby. I have tried few things like replacing ':' with '=' or putting nil in {} but nothing seems to work.
My ruby version is 2.1.5.
IUQ-mini:~ IUQ$ rbenv versions
system
* 2.1.5 (set by /Users/IUQ/.ruby-version)
2.1.7
2.2.3
The particular code can be found here at line #38.
Few questions over SO points that this could happen due to misplaced braces but I did not see error - again my lack of Ruby knowledge!
Please help me to understand cause of this error and How can I resolve this?
Thanks
That won't work in ruby 1.9 (if in fact JRuby is limiting you to 1.9) as-is since the splat is expected to have a hash immediately following it if it's the first argument.
You can do something like this:
def self.run (environment = {}, timeout = nil, *args)
end
The only rub is you'll have to explicitly pass something (even nil) for timeout if you want to pass stuff in to be args[].
Calabash iOS and Android require ruby >= 2.0.
The latest released version of ruby is recommended.
JRuby of any version is not supported at this time.
Travis build
If you look at the info for that build, you'll see it failed because it was running on ruby 1.9.3.
I believe that you have ruby 2.0 installed. I don't think you are using it.
$ rbenv versions
system
1.8.7-p375
1.9.3-p484
2.0.0-p481
2.1.5
2.2.2
2.2.3
* 2.3.0 (set by /Users/moody/.rbenv/version) <== Active ruby in this dir
jruby-1.7.18
$ rbenv version # Active ruby in this directory
2.3.0
You never mentioned what version of run_loop you are using. You should update to the most recent stable release.
https://github.com/calabash/calabash-ios/wiki/Updating-your-run-loop-version

Why doesn't each_slice work?

I am trying to use the Enumerable#each_slice. It doesn't work on my computer, stating that method is not found.
I am running ruby 1.8.6 (2008-08-11 patchlevel 287) [universal-darwin9.0]
API: http://ruby-doc.org/core/classes/Enumerable.html#M003142
Example:
(1..10).each_slice(3) {|a| p a} # I get NoMethodError: undefined method `each_slice' for 1..10:Range
What am I doing wrong?
In ruby 1.8.6 you have to require 'enumerator' (which is part of stdlib and has been merged into core in 1.8.7+) before using each_slice.
Sadly the ruby-doc lists methods that are added to core classes by stdlib without mentioning where the methods are from.
just compared 1.8.6 to 1.9 and it looks like
(1..10).respond_to? :each_slice
is true in 1.9 and false in 1.8.6. So, the doc you are using is not for 1.8.6. if you can upgrade to a newer version of Ruby easily it should give you that method on the Range.

Resources