Skip to content

Instantly share code, notes, and snippets.

@indirect
Last active December 16, 2015 23:30
Show Gist options
  • Save indirect/5514723 to your computer and use it in GitHub Desktop.
Save indirect/5514723 to your computer and use it in GitHub Desktop.
defined?(super) on Ruby 2.0.0-p0 is different from 1.9.3-p392
± aa+rm |ruby2 ✗| → bundle exec ruby reduced.rb
This is not nil, it is a PG::Result
#<PG::Result:0x007fb632e778a0 @connection=#<PG::Connection:0x007fb632e7fa28>>
This is a PG::Result on 1.9.3, but it is nil on Ruby 2.0 because defined?(super) returned nil
the value of defined?(super) is: nil
nil
|ruby-2.0.0-p0| Lyra-Heartstrings-5 in ~/workspace/makara
± aa+rm |ruby2 ✗| → rvm use 1.9.3
Using /Users/wanelo/.rvm/gems/ruby-1.9.3-p392
|ruby-1.9.3-p392| Lyra-Heartstrings-5 in ~/workspace/makara
± aa+rm |ruby2 ✗| → bundle exec ruby reduced.rb
This is not nil, it is a PG::Result
#<PG::Result:0x007fa343165ec0>
This is a PG::Result on 1.9.3, but it is nil on Ruby 2.0 because defined?(super) returned nil
the value of defined?(super) is: "super"
#<PG::Result:0x007fa343165448>
#!/usr/bin/env ruby
require 'active_record'
module Makara
def self.connection
nil
end
module Connection
# module which gets extended on adapter instances
# overrides execute so it will delegate to the makara adapter once
module Decorator
# if we have a makara adapter and we're not alrady hijacked,
# allow the adapter to handle the execute
def with_makara
adapter = Makara.connection
if adapter && !adapter.hijacking?
yield adapter
else
yield nil
end
end
def execute(*args)
with_makara do |acceptor|
puts "the value of defined?(super) is: #{defined?(super).inspect}"
return (defined?(super) ? super : nil) if acceptor.nil?
acceptor.execute(*args)
end
end
end
end
end
ActiveRecord::Base.establish_connection(:adapter => "postgresql", :database => "makara_test")
con = ActiveRecord::Base.connection
puts "This is not nil, it is a PG::Result"
p con.execute("select 1")
puts
con.extend ::Makara::Connection::Decorator
puts "This is a PG::Result on 1.9.3, but it is nil on Ruby 2.0 because defined?(super) returned nil"
p con.execute("select 1")
@indirect
Copy link
Author

indirect commented May 3, 2013

This code, on the other hand, works correctly on both 1.9.3 and 2.0.0:

module Makara  
  module Connection
    module Decorator

      def execute(*args)
        acceptor = nil
        puts "the value of defined?(super) is: #{defined?(super).inspect}"
        return (defined?(super) ? super : nil) if acceptor.nil?
        acceptor.execute(*args)
      end

    end
  end
end

@indirect
Copy link
Author

indirect commented May 3, 2013

To make things even more awesome, this breaks Rspec as well for the same code:

# Works on 1.9.3 but not 2.0.0
master.should_receive(:execute).with(select, nil).and_call_original

# Works on both 1.9.3 and 2.0.0
result = master.execute(select)
master.should_receive(:execute).with(select, nil){ result }

@indirect
Copy link
Author

indirect commented May 3, 2013

Extremely minimal example courtesy of @fxn:

class C
  def x
  end
end

module M
  def b
    yield
  end

  def x
    b do
      # On 1.9.3, this is "super", but on 2.0.0 it is nil
      p defined?(super)
    end
  end
end

c = C.new
c.extend M
c.x

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment