[#3986] Re: Principle of least effort -- another Ruby virtue. — Andrew Hunt <andy@...>

> Principle of Least Effort.

14 messages 2000/07/14

[#4043] What are you using Ruby for? — Dave Thomas <Dave@...>

16 messages 2000/07/16

[#4139] Facilitating Ruby self-propagation with the rig-it autopolymorph application. — Conrad Schneiker <schneik@...>

Hi,

11 messages 2000/07/20

[ruby-talk:04171] Re: Basic variable question

From: ts <decoux@...>
Date: 2000-07-22 11:18:12 UTC
List: ruby-talk #4171
>>>>> "J" == Johann Hibschman <johann@physics.berkeley.edu> writes:

J> go in some namespace, right?  If I defined a class in test.rb and
J> loaded it, the name of that class would be inserted into the global
J> namespace, 

 When you define a class or a module, ruby will define a constant variable
 with the same name.

 For example, if you have this file :

 class Toto
 end

 module Tutu
    class Titi
    end
 end

 and you want to retrieve the VALUE associated for each class and module in
 C, you must write :

  tt_cToto = rb_const_get(rb_cObject, rb_intern("Toto")); # class Toto
  tt_mTutu = rb_const_get(rb_cObject, rb_intern("Tutu")); # module Tutu
  tt_cTiti = rb_const_get(tt_mTutu, rb_intern("Titi"));   # class Titi in Tutu

 i.e. Titi is defined in Tutu, not in the global namespace.

J> but simple variables are not, correct?

 yes, look at parse.y. When ruby see the keyword 'class', 'module', 'def'
 it will create a new local_table (local variable are stored in this
 table). For example for a class (my comment are in /* */)

                | kCLASS cname superclass
                    {
                        if (cur_mid || in_single)
                            yyerror("class definition in method body");

                        class_nest++;
/*
           new constant variable
*/
                        cref_push();
/*
           new local table for local variables
*/
                        local_push();
                    }
                  compstmt
                  kEND
                    {
/*
         it create a node for the new class
*/
                        $$ = NEW_CLASS($2, $5, $3);
/*
   if you look at node.h you'll see for NEW_CLASS

#define NEW_CLASS(n,b,s) rb_node_newnode(NODE_CLASS,n,NEW_CBODY(b),(s))
#define NEW_CBODY(b) (cur_cref->nd_body=NEW_SCOPE(b),cur_cref)
#define NEW_SCOPE(b) rb_node_newnode(NODE_SCOPE,local_tbl(),cur_cref,(b))

   i.e. with NEW_CLASS ruby will create a node NODE_SCOPE where are stored
   the local table (which contain the local variable), and a reference
   to the constant variable 
*/ 
                        fixpos($$, $3);
/* 
   retrieve the old table for local variable
*/ 
                        local_pop();
/*
   retrieve the old reference for constant variable
*/ 
                        cref_pop();
                        class_nest--;
                     }

J> -- 

 a last point : this is at *compile* time that ruby resolve a reference to
 a local variable.

 The example given in the FAQ, with my comment :

      for i in 1..2   ======> new local variable `i' stored in local_table
         if i == 2    ======> ruby search a local variable `i' and find it
           print a    ======> ruby search a local variable `a', and don't
                      ======> find it, this is resolved at *compile* time
                      ======> print a()
         else
           a = 1      ======> new local variable `a' stored in local_table
         end
       end

 A more complete example :

pigeon% cat b.rb
#!/usr/bin/ruby
def a
   "I'm in a()\n"
end

for i in 1..2
   print "i = #{i}\n"
   if i == 2
      print "\tbefore the initialization of a : "
      print a
   else
      a = 1
   end
   print "\tafter the initialization of a : "
   print a
   print "\n"
end
pigeon% 

pigeon% b.rb
i = 1
        after the initialization of a : 1
i = 2
        before the initialization of a : I'm in a()
        after the initialization of a : 1
pigeon% 



Guy Decoux

In This Thread

Prev Next