shlajin
shlajin

Reputation: 1576

Ruby threads: somehow class fields become nil

I'm trying to achieve a socket server on Ruby with multiply rooms, where people can send chat messages to each other, for example.

The code is pretty simple: Main file:

require 'room'  
require 'socket'
room = Room.new

### handle connections
Thread::abort_on_exception=true
server = TCPServer.open(2000)   # Socket to listen on port 2000
puts 'Open socket at 2000 port'
loop {                          # Servers run forever
  room.handle_player server.accept
}

room.rb

require 'player'
class Room
  @players = []

  attr_accessor :players

  def initialize

  end

  def handle_player(connection)
    puts ' New client connected!'
    Thread.start(connection, self) do |client, room|
      player = Player.new connection, room
      @players.push player
    end
  end

  def broadcast(message)
    puts "Players is #{@players.class}" #NilClass !
  end
end

player.rb

class Player
  def initialize(connection, room)
    @room = room
    while line = connection.gets
      puts 'got line ' + line
      room.broadcast line
    end
  end
end

The problem is that when I call Room#broadcast from a player – it tells me that @players is nil, but it isn't! How that can be? I'm not sure I'm doing everything correct (my feelings tell me that player should not have direct link to room), but it simplifies the example.

Upvotes: 1

Views: 77

Answers (2)

undur_gongor
undur_gongor

Reputation: 15954

This has nothing to do with threads.

You should put that initialization @players = [] into the initialize of Room.

The way you have it, you do not initialize an instance variable of your object but an instance variable of the class Room.

Upvotes: 1

Marek Lipka
Marek Lipka

Reputation: 51171

You set @players as a Room's class instance variable.

Instead of this, you should put this in your initialize method:

def initialize
  @players = []
end

Upvotes: 1

Related Questions