Forum: Ruby Class variable inside block of defining instance method

Posted by aaaa aaaaaaaaaaa (phora)
on 2010-01-24 03:12
Hello.

How do I perform something like this?
https://gist.github.com/6a2aa7e86cad8717541f

It's the @echo variable inside the block I'm talking about, how do I
gain "access" to it?

Sincerely,
phora.
Posted by Robert Klemme (Guest)
on 2010-01-25 13:00
(Received via mailing list)
2010/1/24 Mikkel Kroman <mk@maero.dk>:

> How do I perform something like this?
> https://gist.github.com/6a2aa7e86cad8717541f
>
> It's the @echo variable inside the block I'm talking about, how do I
> gain "access" to it?

This is not a class variable.  It is an instance variable of @listen.

What kind of access do you need?

Kind regards

robert
Posted by Charles Nutter (headius)
on 2010-01-25 14:11
(Received via mailing list)
Ruby doesn't scope quite like that normally, but you can do it using
instance_eval and define_method:

def initialize(server1, server2)
  @echo = echo = IRC::Client.new(*server1)
  @listen = IRC::Client.new(*server2)
  @echo.instance_eval do
    define_method :message_received do |nick, channel, message, *args|
      if channel == "#Pre"
        echo.puts("PRIVMSG #{echo.channel} :#{message}")
      end
    end
  end
end

instance_eval has some quirks, and define_method methods are never as
fast as normal methods (since they have full block dispatch
semantics), but this should do what you need.

- Charlie
Posted by Robert Klemme (Guest)
on 2010-01-25 14:53
(Received via mailing list)
2010/1/25 Charles Oliver Nutter <headius@headius.com>:
>      end
>    end
>  end
> end
>
> instance_eval has some quirks, and define_method methods are never as
> fast as normal methods (since they have full block dispatch
> semantics), but this should do what you need.

Unlikely, since the method was defined on @listen and not @echo. :-)
This is probably a better solution:

def initialize(server1, server2)
  @echo   = IRC::Client.new(*server1)
  @listen = IRC::Client.new(*server2)

  class <<@listen
    attr_accessor :echo
  end

  @listen.echo = @echo

  def @listen.message_received(nick, channel, message, *args)
    if channel == "#Pre"
      echo.puts("PRIVMSG #{echo.channel} :#{message}")
    end
  end
end

Kind regards

robert
Posted by aaaa aaaaaaaaaaa (phora)
on 2010-02-08 14:38
Thanks to both of you, I've used both examples for several tasks.
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.