I have the following code for connecting to websockets
class Connection < AbstractConnection
def initialize
@conn = WebSocket::Client::Simple.connect @url
@conn.on :message do |event|
puts 'received message'
#this is the weird part
puts self
event_data = event.data.to_json
on_message event_data
end
end
end
the weird thing is that inside those blocks self is equal to Websocket:Client:Simple - and those methods I am calling inside the blocks are missing, so there is an error.
the library I am using for connecting to the websocket is this https://github.com/shokai/websocket-client-simple and it uses event emitter gem to emit events when messages are received.
I really would expect the blocks to identify self as where they are created - as they do in .each method.
so the qustion is what is going on, and how can I call local methods.
I really would expect the blocks to identify self as where they are created - as they do in .each method.
Normally this would be what happens, if the method used yield
or blk.call
, but in this case the on
method captures the block as a proc, and later calls it with instance_exec
, so it executes in the context of WebSocket::Client::Simple::Client
.
Unfortunately there is no way to tell from the signature alone what any given method will do with a block passed to it.
One option might be to store the value of self
in a local variable before the block. Local variables are still available from the block when it is executed in a different context.
# capture self
this = self
@conn.on :message do |event|
# ...
# use this to call methods
this.on_message event_data
end