New to Ruby. Receiving error: undefined method `+' for nil:NilClass (NoMethodError)
I do not understand why I am receiving an error for such a simple task of incrementing a value. However, perhaps the error is caused by something else.
What is the cause?
class LinkedList
class Node
attr_accessor :data, :nextNode
def initialize(data = nil, nextNode = nil)
#data = data
#nextNode = nextNode
end
end
#member variables
#head = nil
#size = 0
def initialize
#head = Node.new()
end
def add(val)
curr = #head
while curr.nextNode != nil
curr = curr.nextNode
end
curr.nextNode = Node.new(val)
#size += 1 #<<<-------------------------------------ERROR LINE----------
end
end
list = LinkedList.new()
list.add(0)
Move the declaration for #size into the initialize method:
def initialize(data = nil, nextNode = nil)
#data = data
#nextNode = nextNode
#size = 0
end
Related
I'm having issues understanding this encapsulation. I have instance variables defined with attr_accessor. I'm trying to access them outside class. But they are always nil and returns undefined method.
NoMethodError: undefined method `has_key?' for nil:NilClass
Please help me understand.
class TrieNode
attr_reader :value, :next, :children
def initalize
#value = nil
#children = Hash.new
#next = nil
end
end
class Trie
attr_accessor :root
def initialize
#root = TrieNode.new
end
def build_trie(strs)
cur = #root
strs.each do |str|
str.chars.each do |char|
if cur.children.has_key? char
cur = cur.children[char]
next
else
new_node = TrieNode.new
cur.children[char] = new_node
cur = new_node
end
end
cur = #root
end
end
end
Yes, it is not encapsulation, it is because your object is not instantiated properly, which is caused by a typo
def initalize
#value = nil
#children = Hash.new
#next = nil
end
should be initialize not initalize
I am trying to implement a singly Linked List in Ruby and it works fine until I try to delete all the elements to the list. Deleting the elements seems to work but deleting the last element and calling a to_s method causes a runtime error even though I tried to traverse the list while the next Item is not equal to nil.
Here's my code:
#----- NODE CLASS -----#
class Node
attr_accessor :data, :link # automatically generated getters & setters
# Constructor/Initializer #
def initialize(data = nil, link = nil)
#data = data
#link = link
end
# toString method #
def to_s
#data
end
end #End node class
#----- AbstractList Class -----#
class AbstractList
##listSize
def getSize
return ##listSize
end
# Constructor/Initializer #
def initialize()
#head = nil
##listSize = 0
end
# insert at the front of the list #
def insertFront(item)
if #head == nil
#head = Node.new(item)
else
temp = Node.new(item)
temp.link = #head
#head = temp
end
##listSize += 1
end
# insert at the front of the list #
def insertBack(item)
if #head == nil
#head = Node.new(item)
else
current = #head
while current.link != nil
current = current.link
end
newNode = Node.new(item, nil)
current.link = newNode
end
##listSize += 1
end
# remove from the front of the list #
def removeFront()
if empty()
raise "List is empty"
end
current = #head
#head = #head.link
current = nil
##listSize -= 1
end
# check if list is empty #
def empty()
result = false
if ##listSize == 0
result = true
end
return result
end
# toString method #
def to_s
result = []
current = #head
while current.link != nil
result << current.data
current = current.link
end
result << current.data
return result
end
end #End AbstractList class
#----- MAIN METHOD -----#
#node = Node.new("Ten", "twenty")
#print node.to_s
list = AbstractList.new()
list.insertFront("One")
list.insertFront("Two")
list.insertFront("Three")
list.insertFront("Four")
list.insertBack(10)
list.insertBack(20)
list.insertBack(30)
list.insertBack(40)
print list.to_s
puts " List size => #{list.getSize}"
list.removeFront()
list.removeFront()
list.removeFront()
list.removeFront()
list.removeFront()
list.removeFront()
list.removeFront()
print list.to_s
puts " List size => #{list.getSize}"
list.removeFront()
It prints out the following and causes an error when I remove the last element and print:
>["Four", "Three", "Two", "One", 10, 20, 30, 40] List size => 8
>[40] List size => 1
>List size => 0
>in `to_s': undefined method `link' for nil:NilClass (NoMethodError)
and the error points to the line
while current.link != nil
in the to_s method of the Abstract list.
When last element is deleted then #head is set to nil
Now, you are calling to_s on list
def to_s
result = []
current = #head
while current.link != nil
result << current.data
current = current.link
end
result << current.data
return result
end
Here current = #head which is assigned to nil
In next step, while current.link != nil , it will check link for nil which is throwing an error.
Solution : change your while condition to while current and current.link != nil
def to_s
result = []
current = #head
while current and current.link != nil
result << current.data
current = current.link
end
result << current.data if current
return result
end
I have some issues with this code, so, I'm trying to make a linked list but with the first variable I get the next issue:
nodo.rb:34 in 'initialize': wrong number of arguments(1 for 0)
So, the Node class have the actual node and the link, and LinkedList the size and the header.
The problem comes when I try to add a new value but I receive the issue. So I dont know how to fix this problem. I will receive any help you could give me.
class Node
def intialize(data,ref = nil)
#data = data
#refe = refe
end
def get_data
return #data
end
def set_data(newdata)
#dato = newdata
end
def get_ref
return #ref
end
def set_ref(newref)
#ref = newref
end
end
class Linkedlist
def initialize
#size = 0
#header = nil
end
def add_var(value)
#aize = #size + 1
if #header == nil
#header = Node.new(value) #the issue comes here, in the moment when I try to make a new class of Node
else
nodeActual = #header
while nodeActual.get_ref != nil
nodeActual = nodeActual.get_ref
end
nodeActual.set_ref(Node.new(value))
end
end
#def print_list
#end
def get_size
return #size
end
end
list = Linkedlist.new
stop = nil
while stop != -1
a = gets.chomp
if a.to_i == -1
stop = -1
else
list.add_var(a)
end
end
#list.print_list
you have a typo in Node class, rename intialize to initialize (missing i)
I'm new to ruby
I created my own map class
class MyMap
attr_accessor :key,:value
def initialize
self.key = []
self.value = []
end
def pair_push(k, v)
self.key.push(k)
self.value.push(v)
end
...
end
And my own json object
class Json
attr_accessor :index,:data
def initialize
index=MyMap.new
data=MyMap.new
end
def create_index(_index, type, id)
index.pair_push("_index", _index)
index.pair_push("_type", type)
index.pair_push("_id", id)
end
def add_to_data(attName, value)
data.pair_push attName, value
end
...
end
But when I try to use add_to_data
jsonDst.add_to_data(attributeName, arr[i]) I get the following error message
helloWorld.rb:66:in `add_to_data': undefined method `pair_push' for nil:NilClass (NoMethodError)
Note, before I invoke add_to_data I verify that attributeName != nil && arr[i] != nil
In the constructor you should use #instance_variables. In your Json class' constructor, when you refer to data, that's just an uninstantiated local variable. You should use #data instead. Same goes for #index:
class Json
attr_accessor :index,:data
def initialize
#index=MyMap.new
#data=MyMap.new
end
def create_index(_index, type, id)
index.pair_push("_index", _index)
index.pair_push("_type", type)
index.pair_push("_id", id)
end
def add_to_data(attName, value)
data.pair_push attName, value
end
...
end
Here's how it works: http://ideone.com/mpLroq
When I was working on RubyMonk's online exercise "Ruby Primer : Ascent, 3.2 Stacks and Queues" to create a Stack class, I found that I'm not quite understanding the purpose of the self in function push.
class Stack
def initialize(size)
#size = size
#stack = Array.new(#size)
#top = -1
end
def pop
if empty?
return nil
else
result = #stack[#top]
#stack[#top] = nil
#top -= 1
return result
end
end
def push(element)
if full? || element.nil?
return nil
else
#top += 1
#stack[#top] = element
self
end
end
def size
#size
end
def look
#stack[#top]
end
private
def full?
#top == #size - 1
end
def empty?
#top == -1
end
end
It returns the object of class Stack itself, so you could chain method calls like this:
my_stack.push(1).push(2).push(3).size
#=> 3
Each call of push() will result in the original my_stack, so you can keep calling push().