Skip to content

Unable to define == for objects when using Array#delete #6262

Closed

Description

@pusewicz

Defining == method on an object so that it's used for comparison when using Array#delete causes an exception. For some reason, the other becomes an Object, rather than Cell.

Sample code

class Cell
  attr_accessor :id

  def initialize
    @id = rand(1_000_000)
  end

  def ==(other)
    @id == other.id
  end

  def id
    @id
  end
end

cells = Array.new(1_000) { Cell.new }
1_000.times do |i|
  cells.delete(cells.sample)
end

puts "There are #{cells.size} cells left."

Expected

$ mruby test.rb
There are 0 cells left.

Actual

$ mruby test.rb
trace (most recent call last):
        [2] mruby.rb:18
        [1] mruby.rb:19
test.rb:9:in ==: undefined method 'id' (NoMethodError)

Activity

  1. phi-luna commented on May 9, 2024

    @phi-luna
    Contributor

    this error seems to not occur at current master (19d9f48)
    it seems to have been fixed by 14bd875

  2. pusewicz commented on May 9, 2024

    @pusewicz
    ContributorAuthor

    @leviongit I played around, and in fact it's an issue with the Array#index:

    class Cell
      attr_accessor :id
    
      def initialize
        @id = rand(1_000_000)
      end
    
      def ==(other)
        puts "Comparing #{other.class}"
        @id == other.id
      end
    
      def id
        @id
      end
    end
    
    cells = Array.new(1_000) { Cell.new }
    puts cells.index(cells[100])

    Expected

    $ mruby test.rb
    100
    

    Actual

    $ mruby test.rb
    trace (most recent call last):
            [1] mruby.rb:19
    mruby.rb:10:in ==: undefined method 'id' (NoMethodError)
    
  3. matz commented on May 10, 2024

    @matz
    Member

    As general advice, the == method should accept any object as an argument. But we fixed the issue anyway.

  4. added a commit that references this issue on May 10, 2024
    db30b06
  5. pusewicz commented on May 12, 2024

    @pusewicz
    ContributorAuthor

    @matz That's correct, but in my case I knew exactly that there would be only one type of object in the array.

  6. matz commented on May 13, 2024

    @matz
    Member

    Despite of your expectation == method may be called from the library. In fact, the bug was in the find method calling ==.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions