From: Robert Klemme Date: 2010-02-04T19:55:08+09:00 Subject: Re: Where is the magic? On 02/04/2010 11:33 AM, Ilya Lopatkin wrote: > I'm learning Ruby and have found some interesting behaviour which I > cann't understand myself yet. > Here's some code and the output: > class Foo > def self.new(*args) > obj = super > yield > obj > end > end > > Foo.new do > p self > end > > Struct.new("Foo", :foo, :bar) do > p self > end > > => main > => Struct::Foo > > The first output is quite understandable because self is bounded to the > top-level class of the file and is sent to the closure. > But in the second line it seems that scope of self has been changed > somehow. > I've had a fast look on the source file struct.c and haven't found > something special in the new method. > The same thing can also be found in the QtRuby bindings: > require 'Qt4' > > Qt::Application.new(ARGV) do > Qt::Widget.new do > > self.window_title = 'Hello QtRuby v1.0' > resize(200, 100) > > button = Qt::PushButton.new('Quit') do > connect(SIGNAL :clicked) { Qt::Application.instance.quit } > end > > label = Qt::Label.new('Hello Qt in the Ruby way!') > > self.layout = Qt::VBoxLayout.new do > add_widget(label, 0, Qt::AlignCenter) > add_widget(button, 0, Qt::AlignRight) > end > > show > end > > exec > end > > Please, could anybody explain me how does this work. Links will do too. > :) Struct.new uses instance_eval internally: irb(main):001:0> o = Object.new => # irb(main):002:0> o.instance_eval { p self } # => # irb(main):003:0> p self main => main irb(main):004:0> An example more close to what Struct does: irb(main):001:0> class Foo irb(main):002:1> def initialize(&b) irb(main):003:2> printf "in init: %p\n", self irb(main):004:2> instance_eval(&b) irb(main):005:2> end irb(main):006:1> end => nil irb(main):007:0> Foo.new { printf "in block: %p\n", self } in init: # in block: # => # Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/