简体   繁体   中英

Access the attributes of a class instance from within the same class definition in Ruby

Suppose that I have a class "Facility" and I have two instances 'Myhome' and 'Central'. How can I access/modify the attributes of the instance 'Central', whenever an instance of the class is created. Example:

class Facility  
    attr_accessor :name, :address  

    def initialize(name,adrs)
        @name = name
        @address = adrs
    end

    def some_process
        puts "My address #{@address}"
        Central.@address = @address + "something" 
        # I know that this is incorrect usage but 
        # this is the operation that I would like to perform
    end
end
Myhome = Facility.new("Fosters", "B-12 Kensington Farms, Dublin")
Central = Facility.new("Directory", "Not Important")
Myhome.some_process
puts Central.address # This should display the address + "something"  

My objective is to access the attribute 'address' of the instance 'Central' for every other instance of the class Facility, without creating any new classes.

Passing the instance, as Andrey stated, is the recommended way to do it. But another option would be to create a class variable (you do that with two at signs like so: @@class_variable_name ). That would be updated across all instances of the class (kind of like a global variable).

There are two approaches that could be taken here:

  • save an instance within a class instance variable
  • save an instance outside the class and pass it as an argument to the class' instance methods.

Since a particular instance must be saved somewhere, it makes sense to store it within the class (option #1 above). That both confines its scope to the class and simplifies the code.

@baron816 mentions the same approach except he/she advocates the use of a class variable. The problem with class variables is that they are accessible in subclasses. That may not be a problem here, but there are no advantages to using a class variable instead of a class instance variable.

Here's how this approach might be implemented.

class Facility  
  attr_accessor :name, :address  

  def initialize(name, address)
    @name = name
    @address = address
  end

  def saved_instance_set
    self.class.instance_variable_set(:@saved_instance, self)
  end

  def saved_instance_get
    self.class.instance_variable_get(:@saved_instance)
  end

  def addresses
    puts "Address for #{ name } is #{ address }"
    puts "Saved instance address is #{ saved_instance_get.address }"
  end
end

This class might be used as follows.

my_home = Facility.new("Fosters", "B-12 Kensington Farms, Dublin")
  #=> #<Facility:0x...8 @name="Fosters", @address="B-12 Kensington Farms, Dublin">

Now make this the saved instance.

Facility.instance_variables
  #=> [] (confirm there are no class instance variables initially)
my_home.saved_instance_set
  #=> #<Facility:0x...8 @name="Fosters", @address="B-12 Kensington Farms, Dublin"> 
Facility.instance_variables
  #=> [:@saved_instance] (class instance variable has been created)

Now for Bob.

bobs_home = Facility.new("Rikers Island", "Room 253, New York")
  #=> #<Facility:0x...8 @name="Rikers Island", @address="Room 253, New York"> 

Execute addresses for Bob.

bobs_home.addresses

prints

Address for Rikers Island is Room 253, New York
Saved instance address is B-12 Kensington Farms, Dublin

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM