Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8620823
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 12, 20262026-06-12T06:40:26+00:00 2026-06-12T06:40:26+00:00

Just realized that instance_eval yields self as an argument to the associated block (except

  • 0

Just realized that instance_eval yields self as an argument to the associated block (except for a bug in the 1.9.2 version: http://www.ruby-forum.com/topic/189422)

1.9.3p194 :003 > class C;end
1.9.3p194 :004 > C.new.instance_eval {|*a| a}
 => [#<C:0x00000001f99dd0>] 
1.9.3p194 :005 > 

Is this documented/spec’ed somewhere? Looking at ruby-doc:BasicObject, can’t see any block params mentioned.

Is there a reason -apart from some purely historical one- for passing it explicitly when it self is always defined anyway?


The way I was hit by this is:

l = lambda {  }
myobj.instance_eval(&l)  # barks

This worked fine in 1.8.x (I guess because of block arity wasn’t enforced).

Then upgraded to 1.9.2 – and it still worked! That’s a strange coincidence as even though lambda block arguments are strictly enforced (so it would have complained for not declaring the argument for self), however due to the bug linked above – the self actually wasn’t passed in this version..

Then upgraded to 1.9.3 where that bug got fixed, so it started to throwing the argument error – pretty surprising for a minor version change IMHO.

So one workaround is do declare parameter, or make lambda a block instead:

 l = proc {  }
  myobj.instance_eval(&l) # fine

Just thought to describe the full story to help others avoid wasting time the way I did – until this is properly documented.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-12T06:40:28+00:00Added an answer on June 12, 2026 at 6:40 am

    Reading Ruby’s source code, what I can interpret is:

    instance_eval is executing this:

    return specific_eval(argc, argv, klass, self)
    

    which in turn runs:

     if (rb_block_given_p()) {
         if (argc > 0) {
             rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
         }
         return yield_under(klass, self, Qundef);
     }
    

    You can see they pass Qundef for the VALUES argument.

    if (values == Qundef) {
        return vm_yield_with_cref(th, 1, &self, cref);
    }
    

    In that particular line of code, they set manually argc (argument count) to 1 and the argument as “self”. Later on the code that prepares the block sets the arguments to the block to these arguments, hence the first argument = “self” and the rest are nil.

    The code that sets up the block arguments is doing :

       arg0 = argv[0];
    
       ... bunch of code ...
    
         else {
             argv[0] = arg0;
         }
    
         for (i=argc; i<m; i++) {
             argv[i] = Qnil;
         }
    

    Resulting in:

    1.9.3p194 :006 > instance_eval do |x, y, z, a, b, c, d| x.class end
     => Object 
    1.9.3p194 :008 > instance_eval do |x, y, z, a, b, c, d| y.class end
     => NilClass 
    

    Why ? I have no idea but the code seems to be intentional. Would be nice to ask the question to the implementers and see what they have to say about it.

    [Edit]

    This probably is like that because the blocks you pass to instance_eval may or may not be crafted for it (code that depends on self being set to the class you want the block to modify), instead they may assume you are going to pass them the instance you want them to modify as an argument and in this way they would work with instance_eval as well.

    irb(main):001:0> blk = Proc.new do |x| x.class end
    #<Proc:0x007fd2018447b8@(irb):1>
    irb(main):002:0> blk.call
    NilClass
    irb(main):003:0> instance_eval &blk
    Object
    

    Of course this is only a theory and without official documentation I can only guess.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I just realized that this piece of code works well in Firefox but not
I just realized that the MySQLWorkBench destroys the target (makes a replacement) when performing
I just realized that I need to synchronize a significant amount of data collection
I just realized that the method Element.getElementsByTagName(someTagName) returns a nodelist of all elements in
I just realized that i may not be following best practices in regards to
I just realized that when i start a task from within a task and
I just realized that my app, with over 300 users still using an Android
I've just realized that when I use write.table() for saving a data frame in
I had the sample facebook login implementation, and just realized that it stopped working:
I am testing my webpage on a server using preview dns. Just realized that

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.