From: "Berger, Daniel" Date: 2005-03-12T08:47:24+09:00 Subject: Problem with rb_block_given_p() calling context? Hi all, Ruby 1.8.2 Solaris 9 I'm having problem with rb_block_given_p() in a C extension. It seems to be evaluated by a constructor when it shouldn't be. Here's the C code: /* fab.c */ #include "ruby.h" VALUE cFoo, cFab; static VALUE foo_init(VALUE self){ if(rb_block_given_p()) rb_yield(self); return self; } static VALUE fab_get_foos(VALUE klass, VALUE rbNum){ VALUE argv, rbFoo; int i = 0; int n = NUM2INT(rbNum); for(i = 0; i < n; i++){ rbFoo = rb_class_new_instance(0,&argv,cFoo); rb_iv_set(rbFoo,"@some_arg",INT2FIX(i)); if(rb_block_given_p()){ rb_yield(rbFoo); } } return Qnil; } void Init_fab(){ cFab = rb_define_class("Fab",rb_cObject); cFoo = rb_define_class("Foo",rb_cObject); rb_define_method(cFoo, "initialize", foo_init, 0); rb_define_attr(cFoo,"some_arg", 1, 1); rb_define_singleton_method(cFab, "get_foos", fab_get_foos, 1); } Now, if I run a sample script, I get this as the result: # test1.rb require "fab" Fab.get_foos(3){ |f| p f.some_arg } # result nil 0 nil 1 nil 2 Why am I getting the nil? It looks like it's evaluating the call to rb_block_given_p() on the Foo constructor, i.e. in foo_init, even though I'm not explicitly passing it there. A pure Ruby version doesn't seem to have this problem: # test2.rb class Foo attr_accessor :some_arg def initialize yield self if block_given? end end class Fab def self.get_foos(num) 0.upto(num){ |i| f = Foo.new f.some_arg = i yield f if block_given? } end end if $0 == __FILE__ Fab.get_foos(5){ |f| p f.some_arg } end # result 0 1 2 What have I done wrong? Regards, Dan