Working in Ruby, I'm getting an error saying
'add': undefined local variable or method 'food' for #<FoodDB:...
This is the code I'm trying to run
require_relative 'FoodDB.rb'
class Manager
def initialize
food = FoodDB.new
self.create_foodDB(food)
end
def create_foodDB(food)
counter = 1
word = []
file = File.new("FoodDB.txt","r")
while (line = file.gets)
food.addFood(line)
counter = counter + 1
end
file.close
end
end
manager = Manager.new
input_stream = $stdin
input_stream.each_line do |line|
line = line.chomp
if line == "quit"
input_stream.close
end
end
This is FoodDB.rb's code
class FoodDB
def initialize
food = []
end
def addFood(str)
food.push(str)
end
end
I'm not sure what's the problem since it seems like I'm definitely calling the correct method from the FoodDB class. All help is appreciated, thank you!
You need to change food in the FoodDB class to an instance variable:
class FoodDB
def initialize
#food = []
end
def addFood(str)
#food.push(str)
end
end
An instance variable will be available throughout all methods of an instance, while the food variable you used was local to its lexical scope, i.e. only available within the initialize method.
Related
class Player
attr_accessor :card_pile
def initialize
#bust = false
#card_pile = []
end
def bust?
return #cards.inject(:+) > 21
end
end
I have this Player class and have initazlied card_pile variable
class Game
def initialize
#players = []
end
def playing_game
puts "How many players are playing? "
players_amount = gets.chomp.to_i
(0...players_amount).each do
puts ("What is the players name? ")
name = gets.chomp
#players.push(name)
end
puts #players
player = Player.new
player.initialize
while #card_pile.length < 2 do
new_card = Card.new
#card_pile.push(new_card.value)
end
end
I wish to use this variable in the while loop below. Why cannot this be accessed in the way I am hoping it will be?
The error message is: ``playing_game': private method initialize' called for #<Player:0x007fda53073f48 #bust=false, #card_pile=[]> (NoMethodError)
initialize is called automatically when you make a new instance of a class using Player.new. You don't currently have any arguments being passed in to your initialize method, but you have set the instance variable card_pile with attr_accessor, so you can do this:
player = Player.new
while player.card_pile.length < 2 do
new_card = Card.new
player.card_pile.push(new_card.value)
end
trying to pick up ruby through this programming ruby site and i'm stuck on this syntax
class SongList
def initialize
#songs = Array.new
end
def append(aSong)
#songs.push(aSong)
self
end
def deleteFirst
#songs.shift
end
def deleteLast
#songs.pop
end
end
When i go to add a song...
list = SongList.new
list.append(Song.new('title1', 'artist1', 1))
I get this error message:
NameError: uninitialized constant Song ...Programming Ruby
I saw that i need to require the variable Song, but I'm not sure where to do it within the SongList class....
You can use Ruby Struct class :
A Struct is a convenient way to bundle a number of attributes together, using accessor methods, without having to write an explicit class.
class SongList
def initialize
#songs = [] # use [] instead of Array.new
end
def append(aSong)
#songs.push(aSong)
self
end
def delete_first
#songs.shift
end
def delete_last
#songs.pop
end
end
Song = Struct.new(:song_name, :singer, :var)
list = SongList.new
list.append(Song.new('title1', 'artist1', 1))
# => #<SongList:0x9763870
# #songs=[#<struct Song song_name="title1", singer="artist1", var=1>]> var=1>]>
I'm writing a game engine with JRuby, and something goes wrong when I use a global variable. I have only these scripts:
main.rb:
$CLASSPATH << "src.rb"
require 'modules'
require 'SceneMenu'
require 'SceneMap'
$game.setScene(SceneMenu.new)
modules.rb:
$game = Java::MyNamespace::Game::getInstance
module MyGame
def self.cache
return $game.cache # << ERROR OCCURS HERE
end
end
SceneMenu.rb:
class SceneMenu
def initialize
#count = 0
end
def update
if #count == 100
$game.setScene(SceneMap.new)
end
#count += 1
end
end
SceneMap.rb:
class SceneMap
def initialize
#logoTexture = MyGame::cache.load("mylogo.png")
end
end
My problem is that when I launch the game, it always is fine, but when my #count reaches 100, and SceneMap is created, an error occurs saying:
undefined method 'cache' for nil:NilClass
while I have called $game.setScene( ... ) just before.
I do not modify my $game variable at all, so I don't know what happens.
Does someone have an idea of what is going on?
Maybe try changing the code to:
$game = Java::MyNamespace::Game::getInstance
module MyGame
def cache
return $game.cache
end
end
I have finally fixed my problem by writing:
module MyGame
def self.game
return Java::MyNamespace::Game::getInstance
end
end
$game = MyGame::game
I'm trying to make a small game where you go from room to room but when I try to return the value for the next room instead of being the string I intended I get something that looks like this:
#<Roseroom:0x007fe40984c778>
instead of
"skullroom"
This happens whether I use a $global variable or try to return "a string"
Perhaps I'm going about this completely wrong, so if you have any suggestions that would be appreciated as well.
Here is my code, the problem is with class Roseroom not being about to send "skullroom" back to the map class (which is the runner).
$next_room = ''
class Engine
def initialize(stage)
#stage = stage
puts "succesfully initialized game"
#map = Map.new(#stage)
end
end
class Map
def initialize(start)
#start = start
#rooms = {"roseroom" => method(:enterRose),
"skullroom" => method(:enterSkull)
}
runner(#rooms, #start)
end
def runner(map, start)
$next_room = start
while true
room = map[$next_room]
puts $next_room
$next_room = room.call()
#method(:enterSkull).call() #This work if I call it directly
end
end
def enterRose()
#roseroom = Roseroom.new
end
def enterSkull()
#skullroom = Skullroom.new
end
end
class Roseroom
def initialize
puts "succesfully initialized roseroom"
#$next_room = "skullroom"
return "skullroom"
end
def exit
end
end
class Skullroom
def initialize
puts "succesfully initialized skullroom"
Process.exit(1)
end
end
game = Engine.new("roseroom")
I have it here on codepad if that helps:
http://codepad.org/AlpkRIGb
Thanks!
There is nothing in Roseroom class that would return "skullroom"... you may be under the impression that because the last line in initialize is return "skullroom" you would then see "skullroom" returned on a a Roseroom.new but that's not what happens... doing Roseroom.new will always return a new Roseroom object.
you'd be better off defining a next_room method within Roseroom that returns "skullroom"
class Roseroom
def next_room
return "skullroom"
end
Then when you do...
def enterRose
i_am_here = Roseroom.new
i_am_here.next_room
end
Hope this helps.
I'm not sure that's the right title for this question, but I don't know how else to ask it. I have classes that need to be registered globally so they can be called later. I have most of it working except for a very important part. When the child inherits from the parent class, it registers a new instance, but when the on_message class method is called, I can't figure out how to set the instance variables that I need.
class MyExtension < ExtensionBase
on_message '/join (.+)' do |username|
# this will be a callback function used later
end
end
class ExtensionBase
def self.inherited(child)
MainAppModule.registered_extensions << child.new
end
def self.on_message(string, &block)
# these need to be set on child instance
#regex = Regexp.new(string)
#on_message_callback = block
end
def exec(message)
args = #regex.match(message).captures
#on_message_callback.call(args)
end
end
# somewhere else in the code, I find the class that I need...
MainAppModule.registered_extensions.each do |child|
puts child.regex.inspect # this is nil and I dont want it to be
if message =~ child.regex
return child.exec(message)
end
end
How can I design this so that the #regex will be set so I can access it within the loop?
I finally found a solution that works, and I have added now the whole code that is executable. Just store the code e.g. in file callexample.rb and call it by ruby callexample.rb
The main difference of my solution to the question is that the call to on_message now creates the instance with the relevant arguments and registers the created instance. Therefore I have deleted the method inherited because I don't need it any more.
I have added some puts statements to demonstrate in which order the code works.
class MainAppModule ## Added class
##registered_extensions = []
def self.registered_extensions; ##registered_extensions; end
end
class ExtensionBase
attr_reader :regex
def self.on_message(string, &block)
MainAppModule.registered_extensions << self.new(string, block)
end
def initialize(string, block)
#regex = Regexp.new(string)
#on_message_callback = block
end
def exec(message)
args = #regex.match(message).captures
#on_message_callback.call(args)
end
end
class MyExtension < ExtensionBase
on_message '/join (.+)' do |username|
# this will be a callback function used later
puts "Callback of #{self} called."
"returnvalue"
end
end
# somewhere else in the code, I find the class that I need...
MainAppModule.registered_extensions.each do |child|
puts "Value of regex: #{child.regex}" # this is no more nil
message = '/join something'
if message =~ child.regex
puts "On match evalue 'child.exec(message)' to: #{child.exec(message)}"
end
end