Steve B.
Steve B.

Reputation: 57284

Ruby "instance variable not initialized" warning

In writing some "learning the language" code in ruby, as part of a linkedList implementation, I came across this warning:

In the "add" method, the head is created if it doesn't already exist, i.e.

  def add(value)
   new_node=LinkedListNode.new(value)
   if !@head
     @head=new_node
   else
     self.find {|node| node.next ==nil }.next=new_node
   end
  end

I then get the warning

.../linked_list.rb:13: warning: instance variable @head not initialized

How do I get rid of this warning? What's the idiomatic way of doing this?

Upvotes: 15

Views: 10557

Answers (5)

Alex Strizhak
Alex Strizhak

Reputation: 990

I think, in those cases, it's better to use native attr_accessor over the defined? check, for example:

 attr_accessor :head

 def add(value)
   new_node=LinkedListNode.new(value)
   if !head
     self.head=new_node
   else
     self.find {|node| node.next ==nil }.next=new_node
   end
  end

Upvotes: 1

Nerdman
Nerdman

Reputation: 45

You could do something like:

def position
  self.find {|node| node.next.nil? }
end

def head
  @head ||= nil
end

def add value
  node = LinkedListNode.new(value)
  head ? position.next = node : @head = node
end

Upvotes: 0

Logan Capaldo
Logan Capaldo

Reputation: 40336

In addition to Matchu's suggestion, you can also use defined? to initialize @head lazily here without provoking the warning:

if defined? @head
  ...
else
  @head = new_node
end

The normal idiom for this sort of thing is

@head ||= new_node

which will also not provoke the warning, but in this case it seems like you need to do something if @head wasn't defined, and it's not idempotent so ||= is not going to work very well in this case. ||= also has the disadvantage of not being able to distinguish between false, nil or unset. Initializing to nil in initialize is probably the best choice.

Upvotes: 25

Michael Dickens
Michael Dickens

Reputation: 1484

You can't perform the ! operation on @head if it doesn't exist. You need to initialize it first. You should probably declare it as nil.

Upvotes: -4

Matchu
Matchu

Reputation: 85794

You could declare @head as nil in the initialize method, for one.

Upvotes: 11

Related Questions