0

I have this class in file "ghost.rb":

class Ghost
  attr_accessor :fragment

  def initialize(number_of_players)
    @fragment = ''
  end
end

I'm trying to access @fragment from another file in the same directory. Below is "aiplayer.rb" in the same directory.

require "./ghost"

class Aiplayer
  attr_reader :aiplayer

  def initialize
    @aiplayer = Player.new('AI Player')
  end

  def fragment_printer
    Ghost.fragment
  end
end

When I initialize an instance of Aiplayer and call the fragment_printer method on it, I get the following error:

NoMethodError: undefined method `fragment' for Ghost:Class
from aiplayer.rb:17:in `fragment_printer'

I have the attr_accessor there, and so I'm not sure why I cannot reach the fragment variable from outside of the Ghost class. I'm having issues accessing class instance variables from outside of the class. Can anyone give me an explanation on this?

6
  • Where are you creating an instance of Ghost? Commented Feb 13, 2019 at 20:21
  • I haven't created an instance of Ghost. Do I need to do that before trying to access the fragment instance variable off of that? Commented Feb 13, 2019 at 20:28
  • After I type that, it seems like I need to do that as it's not a class variable? Commented Feb 13, 2019 at 20:29
  • How would I be able to connect the two together? I'm testing in Pry and create a new instance of Ghost and Aiplayer (x = Ghost.new, y = Aiplayer.new). How would I be able to modify the fragment_printer method to link to the Ghost fragment piece (which is constantly changing)? Commented Feb 13, 2019 at 20:31
  • 1
    That is an Instance instance variable. A class instance variable would look more like class Ghost; class << self; attr_accessor :fragment; end; end; Commented Feb 13, 2019 at 20:36

2 Answers 2

1

To link the instances you can pass the Ghost instance into the Aiplayer instance at initialization.

class Aiplayer
  attr_accessor :ghost

  def initialize(ghost_to_attach)
    self.ghost = ghost_to_attach
  end

  def fragment_printer
    ghost.fragment
  end

end

x = Ghost.new
y = Aiplayer.new(x)

x.fragment = 'foo'

y.fragment_printer
=> "foo"

This works because the object stored in variable x is the same object stored in the Aiplayer instance ghost attribute.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks Steve, can you explain how ghost is being treated? Based off of "attr_accessor :ghost", is the attached instance of Ghost now an instance variable of the Aiplayer class?
yes, there's nothing magic about attr_accessor :ghost it's just a shortcut way of defining two instance methods... def ghost; @ghost; end and def ghost=(new_value);@ghost = new_value;end so the instance of ghost is stored in the instance variable @ghost of the Aiplayer instance.
1

Can anyone give me a quick explanation of this? I'm sure the explanation is simple, but I can't seem to find an answer as to why.

You wrote Ghost.fragment - it's not instance method, it's class method.

Class methods are not associated with object. You can read about this

Ruby searches method self.fragment in Ghost class, but can't find it.

NoMethodError: undefined method `fragment' for Ghost:Class

That's the reason of your problem.

Further depends on what you want. For example you can write Ghost.new(5).fragment. In this case #fragment is instance method that returns @fragment

I hope I could give you a sense.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.