opal / opal-browser

Browser support for Opal.
MIT License
115 stars 36 forks source link

Browser::Socket prevents instance methods from being called #27

Closed Ravenstine closed 5 years ago

Ravenstine commented 10 years ago

I've been writing my own client-side MVC for my amusement, and came across this problem.

Here is a controller. Note, this is not a Rails controller but inherits from a class called ApplicationController which doesn't do anything at the moment.

class StreamController < ApplicationController

  def debug(str)
    Element.find("#debug").append "<p>#{str}</p>"
  end

  def connect
    Document.ready? do

      debug "yo"

      Browser::Socket.new "ws://localhost:9000/ws" do

        on :message do |e|
          Element.find("#msg").append "<p>#{e.data}</p>"
        end

        on :close do |e|
          debug "socket closed"
        end

        on :open do |e|
          debug "connected..."
        end

        Element.find("#submit").on :click do |e|
          e.prevent_default
          nick = Element.find("#nick").value
          msg = Element.find("#message").value
          write "#{nick}: #{msg}"
          Element.find("#message").value = ""
        end

      end

    end

  end

end

When the controller is initialized, the debug method is called and inserts "yo" into the DOM.

However, when the block passed to Browser::Socket calls the same controller method, I get this error:

Uncaught NoMethodError: undefined methoddebug' for #`

I'm pretty sure this is different behavior than what's displayed in YARV(or RubySpec for that matter).

I cannot tell if this is a problem with opal-browser or Opal itself. If this is a result of the nature of JavaScript, perhaps it should be documented somewhere

meh commented 10 years ago

It's wrong usage of the API.

# @yield if the block has no parameters it's `instance_exec`d, otherwise it's called with `self`

What this means is you have to do this:

Browser::Socket.new "ws://localhost:9000/ws" do |s|
  s.on :close do
    debug "whatever"
  end
end