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

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).

Related

Error fetching status: undefined method `text' for nil:NilClass

I Don't know anything about Ruby, found code below which reports AWS status
https://gist.github.com/ktheory/1604786
/1.rb https://status.aws.amazon.com/rss/a4b-us-east-1.rss
Error fetching status: undefined method `text' for nil:NilClass
ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]
latest_status = xml_doc.css("item title").first.text
print lastest_status
in `<main>': undefined method `text' for nil:NilClass (NoMethodError)
If first comes up empty and returns nil you can't just blunder along or your code will crash. You need to tread carefully:
latest_status = xml_doc.css("item title").first&.text
Or, if you're using an older version of Ruby and have ActiveSupport from Rails:
latest_status = xml_doc.css("item title").first.try(:text)
Or else you're going to need to do it the hard way:
latest_status = xml_doc.css("item title").first
latest_status &&= latest_status.text
You should probably figure out why that selector isn't working as it might not be correct and ends up returning nothing.

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

undefined method `executeScript' for #<Selenium::WebDriver::Chrome::Bridge:0x007ffd0fa16e90>

undefined method executeScript' for <Selenium::WebDriver::Chrome::Bridge:0x007ffd0fa16e90> Did you mean? execute_script (NoMethodError)
I'm getting this error on any line with element.fire_event('onClick')
Chrome version 53.0.2785.143 (64-bit)
ChromeDriver 2.24.417412
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin16]
I'm using selenium-webdriver/page object.. I defined my element..
checkbox(:check_the_box, :id => 'checkboxid')
then tried to execute a fire_event on it..
check_the_box_element.fire_event('onClick')
then i receive the error above.
undefined method `executeScript' for # Did you mean? execute_script (NoMethodError)
Exception clearly states, It should be WebDriver#execute_script(script, *args) instead

Date class misbehaves in Ruby 2.0

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

Ruby Gems "NameError: undefined local variable or method 'update' for main:Object" on every command

I'm attempting to set up a Watir environment. I had several issues actually installing the gems necessary, so I uninstalled and reinstalled Ruby 1.9.3 (I'm running Windows 7.) Now, I can't do any installs, updates, etc. from the ruby command line. Here is an example of some simple commands that should work but are not:
C:\Users\Matt Adams>irb
irb(main):001:0> gem -v
NameError: undefined local variable or method `v' for main:Object
from (irb):1
from C:/Ruby193/bin/irb:12:in `<main>'
irb(main):002:0> gem update
NameError: undefined local variable or method `update' for main:Object
from (irb):2
from C:/Ruby193/bin/irb:12:in `<main>'
I can start ruby irb, but that's it. Its almost as if none of the ruby commands were installed. Anyone have any suggestions? Note that I've already done a re-install.
IRB is there for you to try out Ruby commands or snippets and see immediate responses. If you want to install or update gems, I suggest you get off IRB first by running "quit" and follow whatever instructions you have on your hand.

Resources