Home > OS >  How to call instance variables from one function to another function in same class?
How to call instance variables from one function to another function in same class?

Time:12-30

Actually i am new to the oops concepts in ruby, here i want to call the instance variables from one function to another function in same class.but im getting undefined method for second function "one_object"

module User
    class Object
        class << self
            def add_object(items)
                @data={}
                @data.merge!(items)
            end 
            # i want to use above @data = {} for next one_object method after adding items to the add_object method
            def one_object
                @data.merge!({"ext"=>"1.0"})
            end
        end
    end 
end
a = User::Object.add_object({"txt"=>"text_file","csv"=>"csv_file"})
p a.one_object

Expected Output:

{"txt"=>"text_file", "csv"=>"csv_file", "ext"=>"1.0"}

CodePudding user response:

You assign the result of add_object to a (i.e. your a is now a Hash), but next you are going to call one_object on a (but one_object is part of User::Object and not of your Hash instance).

If you add to add_object another line, containing self, you will receive your expected output.

With the change, add_object will return User::Object, and you won't run into your initial issue.

CodePudding user response:

In Ruby, Object is the root class of all objects. Although you can have your own Object class within User, it could cause a lot of confusion.

Let's simplify your problem my removing the User module (it's not relevant to the example) and by renaming Object to Foo (you'll find a better name). To initialize instance variables you can use the initialize method which is invoked by default every time you construct an object via new:

class Foo
  def initialize
    @data = {}
  end
end

foo = Foo.new
#=> #<Foo:0x00007fb551823d78 @data={}>
#                            ^^^^^^^^

That hash you assign to @data will be shared among all instance methods. In addition, each Foo instance will have its own @data hash. To merge! another hash into it, you can use:

class Foo
  def initialize
    @data = {}
  end

  def add(hash)
    @data.merge!(hash)
  end
end

foo = Foo.new
#=> #<Foo:0x00007fbc80048230 @data={}>

foo.add({"abc"=>123})
#=> {"abc"=>123}

foo.add({"def"=>456})
#=> {"def"=>456}

foo
#=> #<Foo:0x00007fbc80048230 @data={"abc"=>123, "def"=>456}>

In order to chain multiple add calls (a so-called fluent interface), you have to return self from within the method:

class Foo
  def initialize
    @data = {}
  end

  def add(hash)
    @data.merge!(hash)
    self # <- like this
  end
end

foo = Foo.new
#=> #<Foo:0x00007ff7408003d8 @data={}>

foo.add({"abc"=>123}).add({"def"=>456})
#=> #<Foo:0x00007ff7408003d8 @data={"abc"=>123, "def"=>456}>

Finally, to add static data, you could simply call your own method:

class Foo
  def initialize
    @data = {}
  end

  def add(hash)
    @data.merge!(hash)
    self
  end

  def add_more
    add({"more" => 789})
  end
end

foo = Foo.new
#=> #<Foo:0x00007f99b20f8590 @data={}>

foo.add({"abc"=>123}).add({"def"=>456}).add_more
#=> #<Foo:0x00007f99b20f8590 @data={"abc"=>123, "def"=>456, "more"=>789}>
  •  Tags:  
  • ruby
  • Related