Deleting an Object in Ruby

How to destroy Ruby object?

Other than hacking the underlying C code, no. Garbage collection is managed by the runtime so you don't have to worry about it. Here is a decent reference on the algorithm in Ruby 2.0.

Once you have no more references to the object in memory, the garbage collector will go to work. You should be fine.

Ruby: deleting object while looping over list with that object

In Ruby you will actually find a glitch if you do what you are saying.

Try this:

objects = [1,2,3,4]
objects.each { |el| objects.delete(el) }
=> [2, 4]

You would expect the result to be an empty array, but is not. We are messing up with the elements of the arr and each gets confused, because the length of the array has changed. The each iterator looks something like this in pseudocode:

count = 0
while length(objects) > count
yield objects[count]
count + 1
end

So, in the example I shown above, the reason why we get [2, 4] can be explained on a step by step analysis on what objects.each { |el| objects.delete(el) } is doing:

  1. We start with 4 (length of objects) > 0.
  2. Number 1 is yielded, and deleted.
  3. count = 1
  4. 3 (length of objects) > 1
  5. Number 3 is yielded and deleted.
  6. count = 2
  7. 2 (length of objects) is not bigger than count
  8. We are done, so we have [2, 4]

There is a better way to do what you are trying, by using delete_if:

new_objects = objects.delete_if {|o| o.withinBounds }

Remove/delete object from array in Ruby based on attribute value

You can use the #reject method to return the array without objects whose :units equals 0:

result.reject { |hash| hash[:units] == 0 }

There's also #reject! and #delete_if, which can be used in the same way as above but both modify the array in place.

Hope this helps!

Deleting an object in Ruby

Right now, they will never be garbage collected, as you are holding a reference in @@all_instances. You could use a finalizer to get the result you want:

class Vehicle
class << self
attr_accessor :count
def finalize(id)
@count -= 1
end

def all #returns an array of all Vehicle objects
ObjectSpace.each_object(Vehicle).to_a
end
end
Vehicle.count ||= 0

def initialize
Vehicle.count += 1
ObjectSpace.define_finalizer(self, Vehicle.method(:finalize))
end
end

100.times{Vehicle.new}
p Vehicle.count # => 100
ObjectSpace.garbage_collect
p Vehicle.count # => 1, not sure why
p Vehicle.all # => [#<Vehicle:0x0000010208e730>]

If you run this code, you will see that it "works", except that there remains one Vehicle that is not garbage collected. I'm not sure why that is.

Your count method could be also defined more simply by returning ObjectSpace.each_object(Vehicle).count

Finally, if you really want to maintain a list of existing Vehicles, you need to store their ID and use ObjectSpace._id2ref:

require 'set'

class Vehicle
class << self
def finalize(id)
@ids.delete(id)
end

def register(obj)
@ids ||= Set.new
@ids << obj.object_id
ObjectSpace.define_finalizer(obj, method(:finalize))
end

def all #returns an array of all Vehicle objects
@ids.map{|id| ObjectSpace._id2ref(id)}
end

def count
@ids.size
end
end

def initialize
Vehicle.register(self)
end
end

Deleting an instance of a class via a method of that class

This is not possible.

Firstly, Ruby is an object-oriented language, which means that all manipulation is done via messages to objects, and all that is manipulated are objects. Variables are not objects, therefore you cannot manipulate them. (The only things you can do with variables are assign a value to them and dereference them.)

And even if you could manipulate variables, you would still need to hunt down every single reference to the object in question and remove it, in order for the object to be eligible for "deletion" (i.e. garbage collection).

How do you delete an ActiveRecord object?

It's destroy and destroy_all methods, like

user.destroy
User.find(15).destroy
User.destroy(15)
User.where(age: 20).destroy_all
User.destroy_all(age: 20)

Alternatively you can use delete and delete_all which won't enforce :before_destroy and :after_destroy callbacks or any dependent association options.

User.delete_all(condition: 'value') will allow you to delete records
without a primary key

Note: from @hammady's comment, user.destroy won't work if User model has no primary key.

Note 2: From @pavel-chuchuva's comment, destroy_all with conditions and delete_all with conditions has been deprecated in Rails 5.1 - see guides.rubyonrails.org/5_1_release_notes.html

Remove unwanted attributes from an object in ruby

u.attributes.except("first_name", "last_name")

Remove Object from Active Record Array

First question, if you don't want the all records, then why even return them from the DB? Why not use a where clause to filter results:

@products = Product.where(<CONDITIONS>)

Second, if you insist on returning all results then filtering, use a .reject block:

@products = Product.all.reject { |p| <CONDITION> }



Related Topics



Leave a reply



Submit