Much of very wide range. The first step is to evaluate how the internal state apparatus to be represented by Whether the story. Then, the defining statement in the class as an example of the state Changes in the city. Following the internal state sentence is a method definition of what an impact. Finally, both the variable definitions and references to observe the behavior of the change.
A typical image of a procedural language, calling the procedure every time the local queer And return to areas where the number of procedures required to perform an information structure (Stack frames) and stored, Stack it. From the top of the stack and procedures Back in the structure to pop back to the previous method. For example Chapter 5 of moths - as described, BEJIKOREKUSHON That program is run C-called true image.
I want to note where the program is running into a stack, just type
It is the location of the program changed or not. For example, a "strange local
Count i
reference "," The current frame i
, please "Oh instruction
Only of this, "frame i
, please" is not write. In other words stack
State "that" will not change the results. That is why procedures, etc.
When I have attempted several times called the code will only have one (Figure 1).
Figure 1: The only change is a stack
Ruby's execution method is basically a process that is nothing other than a chain of calls , Which is essentially the same image have run. That is the same code , Accessed by the local side of the block local variables and variable scope Schou It is a change in the group. And that scope is represented by the stack.
However, Ruby and iterator Proc
scope to use previously used to temporarily return
Or from a stack of Pop pushed only simple to implement. Resona
Ruby is running for the stack piled into the complex. So stack ICHIOU
And said that the list should be considered not just a maybe.
The method calls in addition to the class definition has changed the scope of local variables RISURU, local calls and variable methods do not match the scope of the transition. Other blocks have also split and we do not have to. That is why in this A variety of reasons, as far away as a stack of seven books.
stack pointer | stack frame type | explain | |||
ruby_frame | struct FRAME | method calls recorded | |||
ruby_scope | struct SCOPE | local variable scope | |||
ruby_block | struct BLOCK | block scope | |||
ruby_iter | struct iter | current FRAME or enumeration is | |||
ruby_dyna_vars | struct Varmap | block local variable scope | |||
ruby_class | VALUE | method definition class at | |||
ruby_cref | NODE ( NODE_CREF ) | class nesting information |
C is a stack of seven books, this means that Ruby, Ruby and the execution of simple arithmetic image The seven-fold from the C is supposed to be tough. But the fact is it's not a seven-fold You see, Ruby is 20 times more tough.
First of all these stacks and stacks of the frame (of) the structure of
Let's easy to explain. Defined in the file is eval.c
or env.h
. Basically
These frames are stacked in touch eval.c
…… just do not want, but
gc.c
marked when you need to know the structure for env.h
, has been the
Above.
Of course it is spam gc.c
, even if it is possible, to separate the function so that the Essential
Is required. Then of course slower. That program is normal by the
Do not, however, GABEJIKOREKUTA and evaluation of the core instruments ruby
largest BOTO
RUNEKKU so, even if our function calls once he's not dumb.
ruby_frame
ruby_frame
method is to call a stack of records. Stack frame
Structure is struct FRAME
. Terminology is a little confusing, generic noun, "Su
Tuck frame "It's just a frame, struct FRAME
that FRAME
and writing
Note that divide.
16 extern struct FRAME ( 17 VALUE self; / * self * / 18 int argc; / * * the number of arguments / 19 VALUE * argv; / * argument array * / 20 ID last_func; / * This method FRAME (name called) * / 21 ID orig_func; / * FRAME this method (as defined when the name) * / 22 VALUE last_class; / * last_func receivers class * / 23 VALUE cbase; / * class variables constant search for the origin * / 24 struct FRAME * prev; 25 struct FRAME * tmp; / * GC avoided. See below * / 26 struct RNode * node; / * line running file name and line number * / 27 int iter; / * call with blocks? * / 28 int flags; / * * The following two / 29) * ruby_frame; 33 # define FRAME_ALLOCA 0 / * FRAME stack is in the * / 34 # define FRAME_MALLOC 1 / * FRAME is to ensure that malloc * / (env.h)
First, prev
to be a member of the stack is made of the linked list
Known (see Figure 2).
Figure 2: ruby_frame
ruby_xxxx
is the tip of the stack frame to point to the stack after all
Common to all of the time, so writing.
Members of the first structure self
. rb_eval ()
argument is self
happened
See also the separate self
to remember is why. That level is C
For the function. Say more super
corresponding rb_call_super ()
.
For the function. super
to run the current method is needed receiver
However, rb_call_super ()
side of the call should not have such information. I say
The user's control is shifted to C code at the time of rb_eval ()
break the cycle of the other
. So zero information from the state self
to obtain information on the Contact Kana
Must be the conclusion. And FRAME
in the yard as a CHO
Exactly.
I think about it some more, argc
and argv
is also strange. Variable parameters
It's the end of it from local variables, methods at the start of the same local strange
The number assigned to the argument once and then I got the need to keep it is not
No? This is not going to be used for me, actually another super
NOTA
Because of it. Ruby is no argument super
to call the method parameters and variables
Super-class value method has been handed over to them. In order to
Meanwhile, is variable parameters (equivalent to a local variable area)-placed to take
There will be.
And last_func
and orig_func
difference is alias
and Methods come.
For example
class C def orig () end alias ali orig end C.new.ali
If the case, last_func = ali
, orig_func = orig
.
All in all, this is also a member of super
KARAN, if you will.
ruby_scope
ruby_scope
stack represents a local scope.
Methods module class definitions, including definitions specific definitions of class
The scope of independence. Stack frame structure is struct SCOPE
.
The frame is SCOPE
and call.
36 extern struct SCOPE ( 37 struct RBasic super; 38 ID * local_tbl; / * * An array of local variable name / 39 VALUE * local_vars; / * * local variable storage / 40 int flags; / * * The following four / 41) * ruby_scope; 43 # define SCOPE_ALLOCA 0 / * local_vars alloca is assigned * / 44 # define SCOPE_MALLOC 1 / * local_vars malloc is assigned * / 45 # define SCOPE_NOSTACK 2 / * POP_SCOPE in the * / 46 # define SCOPE_DONT_RECYCLE 4 / * This is generated by SCOPE, Proc * / (env.h)
The first element is struct RBasic
So this is the object of Ruby. That is
It is Proc
for dealing with the object. For example, to consider the following cases:
I try.
def make_counter lvar = 0 return Proc.new (lvar + = 1) end cnt = make_counter () p cnt.call # 1 p cnt.call # 2 p cnt.call # 3 cnt = nil # reference to pieces. Proc here and finally made it unnecessary
This method made Proc
objects are created than the original method itself
Live longer. And the Proc
from the local variables lvar
of reference,
I made Proc
With the disappearance of OKANE to hold local variables.
So GABEJIKOREKUTA it up as you do not not know the timing of release
.
And even bother struct SCOPE
is struct FRAME
cut off from the second reason is
Point. The first is that the class definitions and methods are not a local call
The scope of the independent variables. Second, C-defined method to call
SU Ruby's when the local variable area is not required.
ruby_block
struct BLOCK
and the Ruby's ITERETABUROKKU Proc
object entity,
At some point, the evaluator's like a snapshot. This Kulun
Page also FRAME
SCOPE
the same way as BLOCK
and a rough sketch.
580 static struct BLOCK * ruby_block; 559 struct BLOCK ( 560 NODE * var; / * block parameter (mlhs) * / 561 NODE * body; / * number of body block * / 562 VALUE self; / * BLOCK generation of self * / 563 struct FRAME frame; / * BLOCK ruby_frame generated when a copy * / 564 struct SCOPE * scope; / * BLOCK generated when ruby_scope * / 565 struct BLOCKTAG * tag; / * BLOCK identity * / 566 VALUE klass; / * BLOCK generated when ruby_class * / 567 int iter; / * BLOCK generated when ruby_iter * / 568 int vmode; / * BLOCK generated when scope_vmode * / 569 int flags; / * BLOCK_D_SCOPE, BLOCK_DYNAMIC * / 570 struct RVarmap * dyna_vars; / * * block local variable area / 571 VALUE orig_thread; / * block to generate the thread * / 572 VALUE wrapper; / * block generation when ruby_wrapper * / 573 struct BLOCK * prev; 574); 553 struct BLOCKTAG ( 554 struct RBasic super; 555 long dst; / * destination that is to return * / 556 long flags; / * BLOCK_DYNAMIC, BLOCK_ORPHAN * / 557); 576 # define BLOCK_D_SCOPE 1 / * an independent variable scope block * / 577 # define BLOCK_DYNAMIC 2 / * BLOCK Ruby is obtained from the program * / 578 # define BLOCK_ORPHAN 4 / * origin to the end of the FRAME * / (eval.c)
frame
pointer does not pay attention. This means that struct FRAME
until the contents
For each copy of the fact that you hold. struct FRAME
(for speed)
Stack on a solid machine will be placed in secure, but, BLOCK
of origin FRAME
than
Because of the potential longevity of the case the copy.
Also struct BLOCKTAG
is that the separation is a block from multiple
Proc
may also generate the same block in order to determine that. Vu same
Rock-generated Proc
is the same BLOCKTAG
with.
ruby_iter
Stack ruby_iter
is calling the current method of enumeration
(Block with whether the call). Frame is struct iter
.
But more unity among the stack frame and consider ITER
referred to it.
767 static struct iter * ruby_iter; 763 struct iter ( 764 int iter; / * * following three / 765 struct iter * prev; 766); 769 # define ITER_NOT 0 / * methods are currently evaluating the non-enumeration * / 770 # define ITER_PRE 1 / * * I call the method of enumeration / 771 # define ITER_CUR 2 / * is currently evaluating methods of enumeration * / (eval.c)
Enumeration of the method or not, but should be determined by the unit,
Thus struct FRAME
and another structure that is available, why?
Methods "iterator" If you need to tell it is natural and
The "enumeration," even if the facts must be知らせなけれ.
However, the order BLOCK
to load a whole is very heavy. The caller variables
References such as waste disposal is also increasing. So BLOCK
instead of more small
Com and light ITER
to積もう, he said. It is more
Chapter 16, described the block.
ruby_dyna_vars
Block local variable area. The second part of the frame structure is also seen
struct RVarmap
. It is simply VARS
called.
52 struct RVarmap ( 53 struct RBasic super; 54 ID id; / * variable name * / 55 VALUE val; / * The value * / 56 struct RVarmap * next; 57); (env.h)
Note that I ask is, struct RVarmap
list is the first one in Kulun
It's that time (Figure 3). And one frame in one low -
In response to the local variable scope. "Local variable scope", not "block
KUROKARU variable scope "because the block is nested in places like
He is represented by one list. Blocks separated when the parser and look like,
id = 0
- RVarmap
(header) represented by. This will also further delay.
Chapter 16, described the block.
Figure 3: ruby_dyna_vars
ruby_class
ruby_class
is def
and the method to define when the target class, respectively.
The statement is usually the class definition self
is because the class ruby_class == self
.
, And top-level eval
, instance_eval
a special method in the middle
self! = ruby_class
to be.
ruby_class
frame is simple VALUE
in the frame structure is not. , Etc.
POKU playing a stack of thousand? But it than I ever prev
Po
There is no inter-structure is a lot of it, what do you stack the
The? Answer the following sections.
After the frame is CLASS
to call them.
ruby_cref
ruby_cref
reference to the class respectively.
Frame remains the same nomenclature, CREF
said.
The structure is……
847 static NODE * ruby_cref = 0; (eval.c)
Why…… NODE
. This is simply "does not need a new definition, VALUE
's finger
Up structure "It used to be just. Node type is NODE_CREF
,
The allocation is a member of the following.
union members | access macro | used in the way | |||
u1.value | nd_clss | outside of class ( VALUE ) < td> | |||
u2 | - | - | |||
u3.node | nd_next | previous CREF to hold |
Member name is nd_next
can actually hold that "before (prev)" of CREF
.
For example, following the example of a program to explain the actual figure.
class A class B class C nil # (A) end end end
(A) to evaluate the code when, ruby_cref
is shown in Figure 4.
So on.
Figure 4: ruby_cref
But each time drawing and writing of繁雑is intended to obscure. So in what follows Figure 4 and the same state as follows words to it.
A ← B ← C
PUSH
/ POP
macro
More than a stack frame structure would also push for macro-Pop is
Have already done that. For example FRAME
, PUSH_FRAME ()
and POP_FRAME ()
, the
At this time. Since coming real soon and is using the time to explain it
Especially now.
The main stack is not important, but so, ruby
evaluator of the other
There are several states. I'll list easily. However stack, and these are
Not necessarily. Rather, it is not so much.
variable name | - | meaning | |||
scope_vmode | int | default method definition visibility | |||
ruby_in_eval | int | rating after the start of the Perth | |||
ruby_current_node | NODE * | currently evaluating the file name and line number | |||
ruby_safe_level | int | $ SAFE | |||
ruby_errinfo | VALUE | exception being processed | |||
ruby_wrapper | VALUE | isolated environment for RAPPAMOJURU |
class
statement module
statement, class-specific definitions and the implementation of any
Similar.
Three similar ones continue to look at it is not fun and this is the most
A small number of elements (so simple) module
look at the statement to it.
First of all, module
What sentence? In other words, that is what is起こるべき
module
a statement? Several characteristics of the whole world.
self
in def
write method and the module is defined. These things having to do what I do, it will be on the point. Let's look at the code to it.
module M a = 1 end
NODE_MODULE nd_cname = 9621 (M) nd_body: NODE_SCOPE nd_rval = (null) nd_tbl = 3 [_ ~ a] nd_next: NODE_LASGN nd_cnt = 2 nd_value: NODE_LIT nd_lit = 1: Fixnum
nd_cname
名らしいmodules. cname
is Const NAME or Class NAME, etc.
CHIRAKA. And some have tried to dump nd_body
always
NODE_SCOPE
on. As a member of nd_tbl
table is a local variable
And in that, struct SCOPE
and the name is similar to that at the thought of this
NODE_SCOPE
scope of local variables to produce an important role in the
There is no doubt seem
NODE_MODULE
, rb_eval ()
- NODE_MODULE
handlers to look at. rb_raise ()
relations,
Error handling, and the main topic of the relationship is a thin cut back on BASSARI. So far more than 200 pages
It also cut back on work done on it, because every other source code to be示さなく
Sure.
case NODE_MODULE: ( VALUE module; if (rb_const_defined_at (ruby_class, node-> nd_cname)) ( / * Already created modules to gain the kind of * / module = rb_const_get (ruby_class, node-> nd_cname); ) else ( / * Create a new module and a constant set * / module = rb_define_module_id (node-> nd_cname); rb_const_set (ruby_cbase, node-> nd_cname, module); rb_set_class_path (module, ruby_class, rb_id2name (node-> nd_cname)); ) result = module_setup (module, node-> nd_body); ) break;
First module is ruby_class
(inside the module) on the nest
It defines that you want to see. It is ruby_class
for
rb_const_xxxx ()
to call it understandable. Only once ruby_cbase
for
Players, but they are usually ruby_class
the same, so it's fine to ignore.
This difference is an issue that first and foremost.
The first half, if
, divided into the modules, Predefined already whether or not
Check. Ruby is one of several modules that can "add" definition
Because you can.
module M def a # M # a define end end Add module M # define (or redefine not override) def b # M # b define end end
This program is a module M
in a
and b
is defined by the two methods.
In this case, the second M
definition of the module M
is already in constant or
And, when used alone to retrieve it. Constant M
If there is no definition of the first
And ( rb_define_module_id ()
) to make the module.
Finally module_setup ()
However, this function is performed on the body module statement.
Sentence statement modules as well as class and class-specific statement of module_setup ()
run.
"None of the three similar statement," and said it is the reason.
Let's argument node-> nd_body
( NODE_SCOPE
) that the passing
The attention you want.
module_setup ()
Module, or class, or class-specific body of the execution sentence is carried out
module_setup ()
. Ruby stack of mass action is finally coming to tell me.
3424 static VALUE 3425 module_setup (module, n) 3426 VALUE module; 3427 NODE * n; (3428 3429 NODE * volatile node = n; 3430 int state; 3431 struct FRAME frame; 3432 VALUE result; / * OK * / 3433 TMP_PROTECT; 3434 3435 frame = * ruby_frame; 3436 frame.tmp = ruby_frame; 3437 ruby_frame = &frame; 3438 3439 PUSH_CLASS (); 3440 ruby_class = module; 3441 PUSH_SCOPE (); 3442 PUSH_VARS (); 3443 / * (A) ruby_scope-> local_vars initialization * / 3444 if (node-> nd_tbl) ( 3445 VALUE * vars = TMP_ALLOC (node-> nd_tbl [0] +1); 3446 * vars + + = (VALUE) node; 3447 ruby_scope-> local_vars = vars; 3448 rb_mem_clear (ruby_scope-> local_vars, node-> nd_tbl [0]); 3449 ruby_scope-> local_tbl = node-> nd_tbl; 3450) 3451 else ( 3452 ruby_scope-> local_vars = 0; 3453 ruby_scope-> local_tbl = 0; 3454) 3455 3456 PUSH_CREF (module); 3457 ruby_frame-> cbase = (VALUE) ruby_cref; 3458 PUSH_TAG (PROT_NONE); 3459 if ((state = EXEC_TAG ()) == 0) ( 3460 if (trace_func) ( 3461 call_trace_func ( "class", ruby_current_node, ruby_class, 3462 ruby_frame-> last_func, 3463 ruby_frame-> last_class); 3464) 3465 result = rb_eval (ruby_class, node-> nd_next); 3466) 3467 POP_TAG (); 3468 POP_CREF (); 3469 POP_VARS (); 3470 POP_SCOPE (); 3471 POP_CLASS (); 3472 3473 ruby_frame = frame.tmp; 3474 if (trace_func) ( 3475 call_trace_func ( "end", ruby_last_node, 0, 3476 ruby_frame-> last_func, ruby_frame-> last_class); 3477) 3478 if (state) JUMP_TAG (state); 3479 3480 return result; 3481) (eval.c)
In one breath to read the rather too large. IRANA likely, it's time to cut back to it.
First trace_func
消せるArea is unconditional.
Idiom relationship tag is visible, so it will become more clear,
Ruby's ensure
to represent the SHIMAOU.
Starting immediately after the function, eliminating the argument n
to a local variable node
to the assignment,
node
in volatile
and they have another assignment that is not completely
This is to avoid known GC. So the first argument from node
to have
Meaning is not changed.
The first half of the function, ruby_frame
and had to mess it up and
Late ruby_frame = frame.tmp
is nothing if not in pairs.
Here is a look at the future, just ruby_frame
- push pop
and
Consider it.
Also (A) to comment on the code ruby_scope-> local_vars
initialization, and will
I stopped by. Later.
Consequently, the only summarized below.
static VALUE module_setup (module, node) VALUE module; NODE * node; ( struct FRAME frame; VALUE result; push FRAME PUSH_CLASS (); ruby_class = module; PUSH_SCOPE (); PUSH_VARS (); ruby_scope-> local_vars initialization PUSH_CREF (module); ruby_frame-> cbase = (VALUE) ruby_cref; begin result = rb_eval (ruby_class, node-> nd_next); ensure POP_TAG (); POP_CREF (); POP_VARS (); POP_SCOPE (); POP_CLASS (); pop FRAME end return result; )
node-> nd_next
$ B $ r rb_eval ()
$ B $ 7 $ F $ $ $ k $ N $ G $ 3 $ l $,% b% 8% e ! <% kJ8K \ BN $ N% 3! <% I $ G
$ B $ "$ k $ 3 $ H $ O $$$$$ H $ 7 $ h $ &! # LdBj $ O $ = $ l0J30 $ @! # 8 + $ k $ Y $-%]%$% s% H $ O8 ^ $ D $ "$ k! #
PUSH_SCOPE () PUSH_VARS ()
$ B $ G5 / $ 3 $ k $ 3 $ H PUSH_CLASS ()
$ B $ N8z2L ruby_cref
$ B $ H ruby_frame-> cbase
$ B $ N4X78 ruby_frame
$ B $ r $ $ $ 8 $ C $ F2? $ r $ 7 $ F $ $ $ k $ N $ + $ B = gHV $ KD4:: $ 7 $ F $ $ $ 3 $ &! #
$ B $ = $ l $ H %^%/% m $ NCf $ G2? EY $ b = P $ F $ / $ k
$ B2? EY $ b8 @ $ C $ F $ $ $ kDL $ j% m !<%+% kJQ? T% 9% 3! <% W $ O
$ BKAF, $ N
$ B $ = $ l $ G
$ B $ 5 $ F! "
$ B $ 3 $ N
$ B $ D $ ^ $ j $ I $ & $ d $ i $ 3 $ l $ O
$ B @ 5D> $ K8 @ $ & $ HI.
$ B% Q! <% 5 $ GMQ0U $ 7 $?% M !<%+% kJQ? TL> $ N% F! <% V% k $ r $ = $ N $^$^; H $ C $ F $ $ $ k! # $ 3 $ N% F! <
$ B% V% k $ O $ $ $ D2rJ | $ 5 $ l $ k $ N $ @ $ m $&!#$=$ l $ O $ 3 $ N
$ B $^$?$=$ N0lJ) $ G% m !<%+% kJQ? T $ N
$ B $ 7 $ + $ 7 !"$=$ l $ J $ i: # EY $ O
$ B $ = $ 7 $ F: G8e $ K! "
$ B TMP_ALLOC () $ B $ rFI $ b $ &! #
$ B $ 3 $ N %^%/% m $ O module_setup () $ B $ N: G = i $ N $[$&$ K $ R $ C $ = $ j $ HB8: _ $ 9 $ k
$ B $ J $ <
$ B! D! D% m !<%+% kJQ? T $ rDj5A $ 7 $ F $ $ $ k $ + $ i! # $ H $$$&$ N $, Ez $($@!#
$ BBh5 $ B> O! X %,!]% Y! <% 8% 3% l% /% 7% g% s! Y $ G2r @ b $ 7 $? $ H $ * $ j! "
$ B0lJ }!"??$ N
$ B $ H $ 3 $ m $ G! "$ J $ <$ 3 $ 3 $ ^ $ G $ 7 $ F
$ B% 9%?% C% /
$ B $ J $ <
$ B $ 3 $ 3 $ G! "
$ B $ 9 $ k $ H; D $ kLdBj $ O
$ B: G8e $ K
$ B %]%$% s%? $ G $ O $ J $$!#$ D $ ^ $ j $ 3 $ l $ O% ^% 7% s% 9%?% C% /> e $ K < code> FRAME $ B $ r% Y%? CV $ - $ G3NJ]
$ B $ 9 $ k $ H $ $ $ & 0UL # $ G $ "$ k! # Ruby $ B% 9%?% C% / $ N4IM) 9 = B $ $ b% m !<%+% kJQ? TNN0h $ b% ^% 7% s
$ B% 9%?% C% /> e $ @ $ C $?$,!"$ J $ s $ H
$ B $ = $ 7 $ F frame $ B $ r2? $ D $ i $ $ $ m $ $ $ m $ 7 $ F $ $ $ k $ H $ 3 $ m $ r8 + $ h $ &! #
$ B $ D $ ^ $ j
$ B $ G $ O $ I $ & $ 7 $ F $ 3 $ 3 $ GAGD> $ K
$ B $ 7 $ + $ 7% b% 8% e! <% KJ8 $ d% /% i% 9J8 $ O% a% =% C% I8F $ S = P $ 7 $ G $ O $ J $$$+$ i $ 3 $ NCf $ K $ O
$ B = P $ F $ - $ F $ [$ 7 $ / $ J $$!#$@$+$ i! V @ Q $^$:$ K! W! "! V: 9 $ 7BX $ ($ k! W $ o $ 1 $ @! #
$ B% b% 8% e! <% KDj5A $ N
$ B $$$/$ D $+%@% s% W $ 7 $ F $_$?$ H $ 3 $ m! "
$ BB3 $ $ $ F
$ BA0H> $ K $ O
$ B! JA $ B! K
$ B! JB $ B! K
$ B! JC $ B! K $ 3 $ 3 $ O% P% 0 $ C $ F $ $ $ k! # K \ = q $ NF ~ 9FD> A0 $ KH / 8 + $ 7 $? $ N $ G = $ @ 5 $ O4V $ K9g $ o $ J
$ B $ + $ C $?!#: G? 7 $ N% 3! <% I $ G $ O $ J $ / $ J $ C $ F $ $ $ k $ O $:$@!#% H % C% W% l% Y% k $ GDj5A $ 5 $ l $?
$ B% a% =% C% I $ r3N private $ B $ K $ 7 $ h $ & $ H $ 7 $?!"$ H $$$&$ N $, 85! 9 $ N0U? ^ $ G $ "$ k! #
$ B! JD $ B! K $ 3 $ l $ ^ $ G $ N $ I $ l $ G $ b $ J $ + $ C $? $ I! "
$ B $ 5 $ F! "
$ B% 3% T! <$ 7 $?$"$ H !"$=$ l $ r
$ B0z? T $ N
$ BK \ BN $ N
$ B $ ^ $ H $ a $ k $ H! "
$ B rb_add_method () $ B $ @! #
$ B $ G $ O! ": G =* E * $ K% /% i% 9 $ N
$ B62 $ i $ /% a% =% C% I $ N% X% C% @ $ r0UL # $ 9 $ k $ N $ @ $ m $&!"< code> NODE_METHOD $ B $, @ hF, $ KIU $ $ $ F
$ B $ * $ j !"$=$ N copy_node_scope () $ B $ G% 3% T! <$ 7 $?
$ B $^$?< code> NODE_SCOPE $ B $ N
$ B $ = $ l $ H: G8e $ K
$ B9M $ ($ F $ _ $ l $ P% 9%?% C% / $ N $ [$ H $ s $ I $ O3F
$ B% m !<%+% kJQ? T $ NBeF ~! &; 2> H $ KI, MW $ J> pJs $ O $ 3 $ 3 $ ^ $ G $ GA4 $ F
$ BEP> l $ 7 $ F $ $ $ k $ N $ GM = B, $, IU $/$@$ m $&!#%]%$% s% H $ O0J2 <$ NFsE$@!#
$ B $ H $$$&$ 3 $ H $ G% m !<%+% kJQ? T; 2> H $ N% N! <% I
Needless to say I think
Chapter 6, and a constant variable in the constant format and store information about the API. Kula is a constant
Su belong to the same method to inherit. It is all too real
But the constant search for the path out of first class, and then wonder, in the superclass
To,
But if you write this nearly constant
This rule, he generalize. That is about the method of constant internal field
If the method definition of "writing" as a starting point to the location of the class outside of class constants
About. And "Methods class where I wrote" Oh, is context-dependent
Resona parser and evaluator of information unless handle both. That's
So outside of class, including the constant references to look at the code.
First
In other words, first class and when the module definition
This method
After the subsequent statement class
And methods
…… Of the mechanism. Confusing.
,
Arguments
And
Moreover, when the super class examine a reversal in the direction of the
Class at a variable
Class is not specific to
This program is both right and left to write the same methods are also defined.
But an increasing number of right書きかたmethod is often the class to write: Yes
Not only pain in the neck. So when you define more specific method to the left
Class-specific definitions in one place, many of them.
However, the two is how to write
So, class, class-specific variables can not and will not judge
The specific class is it that leap. Here again inconsistent.
Resona's designed to emphasize ease of use that way.
By the way, if the constant references to find out from all classes and both書きかた
Ruby, Where's the most complex specifications, and immediately asked if I have to answer multiple assignment.
The multiple assignment It's impossible to grasp the whole picture. I think so thin. YOUSURUNI,
Multiple assignment of the entire design specifications are designed to clean out an involuntary not the God PAKASHIMO
Being made. The new standards will always be "some typical use PERTH
In turn would be useful behavior. " This is true of the entire Ruby, multi -
That is particularly noticeable weight assignment.
Then how do you choose a dense forest in order to spare code? This is a state with a scanner
I like to read, seen as a whole. It is not the whole picture, but
, The overall picture you can not. To cut the number thingy, the Caux
- This is a specification for the design of this code is here to be a……
Respond point by point the way to getting on it.
But this is
First of all street construction staple will be able to see from a tree.
Both are left-hand right-hand
Left-hand side,
This is the right term rating is the only remaining
I'm sorry, in the middle of the list, but here it stopped paying attention to the fourth argument.
So recalled
When the program is是非ともduplication should be avoided, but when you read
Only to have nothing to do with the principle. If the pattern is rather limited copy
Redundant and it is correct. "Optimized for speed," "code of size
Optimization "of the word, but in this case" optimized for readability "
.
So
The following is a code to follow every clause.
(A)
(B) if the right side on one's hands rest on an array of Ruby
(C) If the left side on one's hands all
By the way,
The original work is Copyright © 2002 - 2004 Minero AOKI. PUSH_SCOPE ()
$ B $,% m !<%+% kJQ? tNN0h $ r @ Q $_!"< code> PUSH_VARS () $ B $,% V% m % C% /% m !<%+% k
$ BJQ? TNN0h $ r @ Q $ `$ o $ 1 $@$+$ i!" $ 3 $ NFs $ D $ G? 7 $ 7 $ $% m !<%+% kJQ? T% 9% 3! <% W $,: n $ j
$ B = P $ 5 $ l $ k $ 3 $ H $ K $ J $ k! # $ 3 $ l $ i $ N %^%/% m $ NCf? H $ rDI $ C $ F! "
852 # define PUSH_SCOPE () do (\
853 volatile int _vmode = scope_vmode; \
854 struct SCOPE * volatile _old; \
855 NEWOBJ (_scope, struct SCOPE); \
856 OBJSETUP (_scope, 0, T_SCOPE); \
857 _scope-> local_tbl = 0; \
858 _scope-> local_vars = 0; \
859 _scope-> flags = 0; \
860 _old = ruby_scope; \
861 ruby_scope = _scope; \
862 scope_vmode = SCOPE_PUBLIC
869 # define POP_SCOPE () \
870 if (ruby_scope-> flags & SCOPE_DONT_RECYCLE) (\
871 if (_old) scope_dup (_old); \
872) \
873 if (! (Ruby_scope-> flags & SCOPE_MALLOC)) (\
874 ruby_scope-> local_vars = 0; \
875 ruby_scope-> local_tbl = 0; \
876 if (! (Ruby_scope-> flags & SCOPE_DONT_RECYCLE) & & \
877 ruby_scope! = Top_scope) (\
878 rb_gc_force_recycle ((VALUE) ruby_scope); \
879) \
880) \
881 ruby_scope-> flags | = SCOPE_NOSTACK; \
882 ruby_scope = _old; \
883 scope_vmode = _vmode; \
884) while (0)
(eval.c)
SCOPE
$ B $ b%?% 0 $ H0l = o $ G !"%^% 7% s% 9%?% C% / $ HF14 | $ 5 $; $ F% 9%? % C% / $ r: n $ j = P $ 7 $ F $ $
$ B $ k $ h $&$@!#$?$HyL / $ K0c $ & $ N $ O! "$ 3 $ A $ i $ O% 9%?% C% /% U% l! <% `$ NNN0h <+ BN $ O% R! <
$ B% W $ + $ i3NJ] $ 7 $ F $ * $ j! "% 9%?% C% / 9 = B $ $ r: n $ j = P $ 9 $? $ A $ K% ^% 7% s% 9%?% C% / $ r; H $ C
$ B $ F $ $ $ k $ H $$$&$ H $ 3 $ m $ @ $ m $ &! J? ^ 5 $ B! K! #
$ B? ^ 5: $ B% ^% 7% s% 9%?% C% / $ HSCOPE $ B% 9%?% C% /
SCOPE_
$ B $ J $ s $? $ I $ H $$$&% U% i% 0 $ K $ D $ $ $ F $ O! "
$ B3F% 9%?% C% /% U% l !<%`$ N5-217A <0 $ H% V% m% C% / $ N $ 3 $ H $ rA4 $ FOC $ 7 $ F $ + $ i $ G $ J $ $ $ H
$ B @ bL @ $ G $ - $ J $ $! # Bh16 $ B> O! X% V% m% C% /! Y $ G $ ^ $ H $ a $ F $ d $ k $ 3 $ H $ K $ 9 $ k! #
$ B% m !<%+% kJQ? tNN0h $ N3NJ]
struct SCOPE
$ B $ GI = $ 5 $ l $ k $ N
$ B $@$,!"< code> struct SCOPE $ B $ OJ8; zDL $ j! V% 9% 3! <% W! W $ G $ "$ C $ F!"% M! <% +% kJQ? t $ r
$ B3JG <$ 9 $ k module_setup ()
$ B $ N
3444 if (node-> nd_tbl) (
3445 VALUE * vars = TMP_ALLOC (node-> nd_tbl [0] +1);
3446 * vars + + = (VALUE) node;
3447 ruby_scope-> local_vars = vars;
3448 rb_mem_clear (ruby_scope-> local_vars, node-> nd_tbl [0]);
3449 ruby_scope-> local_tbl = node-> nd_tbl;
3450)
3451 else (
3452 ruby_scope-> local_vars = 0;
3453 ruby_scope-> local_tbl = 0;
3454)
(eval.c)
TMP_ALLOC ()
$ B $ O $ C $ FGC $ B $ r9MN8 $ 7 $ J $ / $ F $ h $ $! K alloca ()
$ B! W $ @! #
node-> nd_tbl
$ B $ K $ O O! X9 = J8LZ $ N9 = C [! Y $ G $ d $ C $?% M !<%+% kJQ? TL> $ N
$ B% F! <% V% k $, F ~ $ C $ F $ $ $ k! # $ D $ ^ $ j nd_tbl [0]
$ B $ K% F! <% V% k% 5 %$%:$, F ~ $ C $ F $ $ $ F! "
$ B; D $ j $ O ID
$ B $ NG [Ns $ K $ J $ C $ F $ $ $ k !#$=$ N% F! <% V% k $ O SCOPE
$ B $ N local_tbl
$ B $ K $ = $ N
$ B $ ^ $ ^ 0 \? "$ 7 !"$^$?% m !<%+% kJQ? T $ NCM $ r3JG <$ 9 $ k $? $ A $ K local_vars
$ B $ r3d $ jEv $ F
$ B $ F $ $ $ k $ h $&$@!#$ 3 $ N $"$?$ j $ OJ6 $ i $ o $ 7 $ $ $ N $ G! V $ 3 $ C $ A $, JQ? TL >! W! V $ 3 $ C $ A $, CM! W
$ B $ H = q $ -9 ~ $ s $ G $*$/$ H $$$$!#< code> tbl $ B $, IU $/$[$&$, L> A0 $ G $ "$ k! #
Local_vars
$ B $ N3d $ jEv $ F $ r: Y $ + $ / 8 + $ F $ _ $ h $&!#< code> local_tbl [0] $ B $,% m! <% +
$ B% kJQ? T $ N? T $@$+$ i! "$ J $<$+% 5 %$%:$ r +1 $ B $ 7 $ F3d $ jEv $ F $ F $ $ $ k! # $ 3 $ 3 $ K $ O: # EY $ O
module_setup ()
$ B $ N0z? t node
$ B! J NODE_SCOPE
$ B! K $ rF ~ $ l $ F $ $ $ k $ h $&$@!#
$ B $ D $ ^ $ j $ 3 $ NJ8 $,=*$ o $ C $? $ H $ 3 $ m $ G? ^ 6 $ B $ N $ h $ & $ K $ J $ k! #
$ B? ^ 6: ruby_scope-> local_vars
node
$ B $ O $ I $ 3 $ G; H $ o $ l $ F $ $ $ k $ N $ @ $ m $ &! #
local_vars
$ B% a% s% P $ r @ v $ C $ F $_$?$,< code> eval.c $ B $ G $ O% $% s % G% C% /% 9 -1
$ B $ X $ N %"%/%;% 9 $ O
$ B8 + Ev $? $ I $ J $ $! # BP>]% U %!%$% k $ r9-$ 2 $ F $ _ $ k $ H! " Gc.c
$ B $ G %"%/%;% 9 $ 7 $ F $$$?!#
815 case T_SCOPE:
816 if (obj-> as.scope.local_vars & &
(obj-> as.scope.flags & SCOPE_MALLOC)) (
817 int n = obj-> as.scope.local_tbl [0] +1;
818 VALUE * vars = & obj-> as.scope.local_vars [-1];
819
820 while (n -) (
821 rb_gc_mark (* vars);
822 vars + +;
823)
824)
825 break;
(gc.c)
node
$ B $ rGC $ B $ + $ iJ] 8n $ 9 $ k $? $ A $ N ; E3] $ 1 $ i $ 7 $$!#$@$,$ J $<%^!<
$ B% / $ 7 $ J $ $ $ H $ $ $ 1 $ J $ $ $ N $ @ $ m $&!#< code> node $ B $ O $ o $ 6 $ o $ 6 volatile
$ B $ J% m !<%+% kJQ? t $ KF ~ $ l
$ B $ F $ "$ k $ N $@$+$ i!" Module_setup ()
$ B $ N
3449 ruby_scope-> local_tbl = node-> nd_tbl;
(eval.c)
node
$ B $,; 2> H $ 5 $ l $ J $ / $ J $ C $? $ H $ - $ G
$ B $ "$ k! # $ G $ O node
$ B $ O $ $ $ D2rJ | $ 5 $ l $ k $ Y $-$@$ m $&!#$=$ l $ O $ 3 $ N9T $ GBeF ~ $ r9T $ C $?
SCOPE
$ B $, A4 $ F> C $ ($ F $ + $ i $ G $ "$ k! # $ G $ O $ = $ l $ O $ $ $ D $ N $ 3 $ H $ @ $ m $&$+!#
SCOPE
$ B $ O $ = $ l $, @ 8 @. $ 5 $ l $ k860x $ K $ J $ C $? J8 $ h $ j $ bD9 @ 8 $ - $ 9 $ k $ 3 $ H $,$"$ k! #
$ BBh16 $ B> O! X% V% m% C% /! Y $ G @ bL @ $ 9 $ k $ H $ * $ j! " Proc
$ B% *% V% 8 %'%/% H $ r @ 8 @. $ 9 $ k $ H $ =
$ B $ 3 $ + $ i SCOPE
$ B $,; 2> H $ 5 $ l $ k $ + $ i $@!#$ D $ ^ $ j module_setup ()
$ B $,=*$ o $ C $ F $ b $ =
$ B $ 3 $ G: n $ C $? SCOPE
$ B $, MQ: Q $ _ $ K $ J $ k $ H $ O8B $ i $ J $$!#$@$+ $ i node
$ B $ O
module_setup ()
$ B! J $ N% 9%?% C% /% U% l !<%`! K $ + $ i; 2> H $ 5 $ l $ F $ $ $ k $ @ $ 1 $ G $ OIT == J,
$ B $ G! " SCOPE
$ B $ + $ i! VD> @ \ $ K! W; 2> H $ 5 $ l $ F $ $ $ J $ / $ F $ O $ J $ i $ J $ $ $ N $ @! #
volatile node
$ B $ b30 $; $ J $$!#$ G $ J $ $ $ H
local_vars
$ B $ KBeF ~ $ 9 $ k $ ^ $ G $ N $"$$$@< code> node $ B $, Ch $ KIb $ $ $ F $ 7 $ ^ $ & #
SCOPE
$ B $ N local_vars
$ B $,$^$:$ $ $ N $ G $ O $ J $$$@$ m $&$+!#
TMP_ALLOC ()
$ B $ O8 @ $ C $? $ H $ * $ j% 9%?% C% / 3d $ jEv $ F $ J $ N $ G! " module_setup ()
$ B $ N
$ B =* N; $ HF1; ~ $ KL58z $ K $ J $ C $ F $ 7 $^$&!#$ 3 $ l $, Proc $ B $ r @ 8 @. $ 7 $?; ~ E @ $ G
$ B $$$-$ J $ j malloc ()
$ B3d $ jEv $ F $ K @ Z $ jBX $ ($ k $ h $ & $ K $ J $ C $ F $ $ $ k $ N $@!#> \ $ 7 $ $ $ 3 $ H $ O
$ BBh16 $ B> O! X% V% m% C% /! Y $ G2r @ b $ 9 $ k! #
Rb_mem_clear ()
$ B $ O0 $ B = Qnil
$ B = nil
$ B $ K = i4 | 2 = $ 5 $ l $ k! #
TMP_ALLOC ()
TMP_PROTECT
$ B $ HAH $ K $ J $ C $ F $ $ $ k! # E57? E * $ J; H $$$+$?$ O $ 3 $&$@!#
VALUE * ptr;
TMP_PROTECT;
ptr = TMP_ALLOC (size);
TMP_PROTECT
$ B $,% m !<%+% kJQ? TDj5A $ N0LCV $ K $ "$ k $ + $ H $$$&$ H! D! D
$ BDj5A $ r8 + $ F $ _ $ h $ &! #
1769 # ifdef C_ALLOCA
1770 # define TMP_PROTECT NODE * volatile tmp__protect_tmp = 0
1771 # define TMP_ALLOC (n) \
1772 (tmp__protect_tmp = rb_node_newnode (NODE_ALLOCA, \
1773 ALLOC_N (VALUE, n), tmp__protect_tmp, n), \
1774 (void *) tmp__protect_tmp-> nd_head)
1775 # else
1776 # define TMP_PROTECT typedef int foobazzz
1777 # define TMP_ALLOC (n) ALLOCA_N (VALUE, n)
1778 # endif
(eval.c)
# ifdef C_ALLOCA
$ B $ N! J% M% $% F% #% V $ N
alloca ()
$ B $, $ J $ $! K4D6-$ G $ O malloc ()
$ B $ G alloca ()
$ B $ r %(%_% e% l! <% H $ 7 $ F $ $ $ k! #
$ B $ 7 $ + $ 7% a% =% C% I $ N0z? T $ H $$$&$ N $ OEvA3 VALUE
$ B $ G $ "$ j!"% R! < % W $ K VALUE
$ B $ rCV $ $
$ B $ F $ 7 $^$&$ HGC $ B $ G8! = P $ G $ - $ J $ / $ J $ C $ F $ 7 $^$&!#$=$ 3 $ G NODE
$ B $ r7PM3 $ 7 $ FL5M) LpM)
GC $ B $ NBP>] $ K $ 9 $ k! J? ^ 7 $ B! K! #
$ B? ^ 7: NODE
$ B7PM3 $ GNN0h $ r% 9%?% C% / $ KHK $.;_$ a $ k
alloca ()
$ B $,$"$ k4D6-$ G $ OIaDL $ K alloca ()
$ B $ r; H $ ($ P $$$$$ N $ G
TMP_PROTECT
$ B $ OI, MW $ J $$!#$=$ 3 $ GL532 $ J <0 $ rE, Ev $ KF ~ $ l $ F $*$/!#
alloca ()
$ B $ r; H $$$?$,$ k $ N $ @ $ m $&$+!#
$ B $ = $ NM) M3 $ OC1 $ K! V alloca ()
$ B $ N $[$&$,< code> malloc () $ B $ h $ jB .$$$+$ i! W $@$=$&$@!#
$ B $ = $ N $ / $ i $ $ $ N0c $ $ $ O $ I $ & $ G $ b $$$$$ h $ & $ J5 $ $ b $ 9 $ k $ N $@$,!" $ J $ K $ 7 $ m
$ BI> 2A4o% 3% "$ O ruby
$ B: GBg $ N% \% H% k% M% C% / $ J $ N $ G!" 0J2 $ B% a% =% C% IDj5A @ h $ NJQ99
ruby_class
$ B $ NCM $,$=$ N $ H $ - $ N% a% =% C% I $ NDj5A @ h% /% i % 9 $ K $ J $ k! # 5U $ K8 @
$ B $ & $ H ruby_class
$ B $ KCM $ r% W% C% 7% e $ 9 $ k $ HDj5A @ h% /% i% 9 $, JQ $ o $ k! # $ = $ l $ 3 $=$,%/% i
$ B% 9J8 $ KI, MW $ J $ 3 $ H $@!#=>$ C $ F module_setup ()
$ B $ G $ b PUSH_CLASS ()
$ B $ 7 $ J $ 1 $ l $ P $ J $ i
$ B $ J $$!#$=$ l $, $ 3 $ N% 3! <% I $ @! #
PUSH_CLASS ();
ruby_class = module;
$ B! '
$ B! '
POP_CLASS ();
PUSH_CLASS ()
$ B $ 7 $ F $ + $ i ruby_class
$ B $ K2 ~ $ a $ FBeF ~ $ 7 $ F $ $ $ k $ N $ @ $ m $ &! #
$ B $ 3 $ l $ ODj5A $ r8 + $ k $ H0U30 $ H $ "$ C $ 5 $ j $ o $ + $ k! #
841 # define PUSH_CLASS () do (\
842 VALUE _class = ruby_class
844 # define POP_CLASS () ruby_class = _class; \
845) while (0)
(eval.c)
PUSH_CLASS ()
$ B $ 7 $ F $ b ruby_class
$ B $, = q $ -49 $ o $ k $ o $ 1 $ G $ O $ J $ $ $ N $ G !"$=$ N $ "$ H $ K PUSH_CLASS ()
$ B $ N0z? t $ K% /% i% 9 $ rEO $ 9 $ h $ & $ K $ 9 $ l $ P $ b $ C $ H $ - $ l $ $ $ J %^%/% m $ K $ J
$ B $ k $ 8 $ c $ J $$$+! D! D $ H $$$&$ N $ OA4 $/$=$ NDL $ j $ J $ N $@$,!"% W% C% 7% e $ 9 $ kA0 $ K% /% i% 9
$ B $, F @ $ i $ l $ J $ $> l = j $,$"$ k $? $ A $ K $ 3 $&$$$&$ 3 $ H $ K $ J $ C $ F $ $ $ k! #
$ B% /% i% 9 $ N% M% 9% H
ruby_cref
$ B $ O ruby_cref
$ B $, @ Q $ ^ $ l $ k $ N $ OEvA3M = A [$ G $ - $ k! #
module_setup ()
$ B $ G $ O $ 3 $ s $ J $ U $ & $ K @ Q $ s $ G $$$?!#
PUSH_CREF (module);
ruby_frame-> cbase = (VALUE) ruby_cref;
$ B! '
$ B! '
POP_CREF ();
Module
$ B $ ODj5ACf $ N% b% 8% e! <% K $ G $" $ k! #
PUSH_CREF ()
$ B $ H POP_CREF ()
$ B $ NDj5A $ b8 + $ F $ * $ 3 $ &! #
849 # define PUSH_CREF (c) \
ruby_cref = rb_node_newnode (NODE_CREF, (c), 0, ruby_cref)
850 # define POP_CREF () ruby_cref = ruby_cref-> nd_next
(eval.c)
PUSH_SCOPE ()
$ B $ J $ I $ N $ h $ & $ J $ H $ s $ G $ b $ J $ $ 9) IW $,$"$ k $ o $ 1 $ G $ b $ J $ /! "
$ BHs> o $ K07 $ $ $ d $ 9 $$!#$ d $ O $ j $?$^$ K $ O $ 3 $&$$$&$ N $ b $ J $ $ $ H: $ $ k #
ruby_frame-> cbase
$ B $, 2? $ R0UL # $ 7 $ F $ $ $ k $ N $ + $ H $ $ $ & $ 3 $ H $@$,!"
$ B $ 3 $ l $ O8 =: _ $ N FRAME
$ BFb $ + $ iDj? T $ d% /% i% 9JQ? T $ r; 2> H $ 9 $ k $ N $ K; H $ &> pJs $ G $ "$ k! #
$ B> \ $ 7 $ $ $ 3 $ H $ OK \> O $ N: G8e $ N @ a $ G8 + $ F $$$/!#
$ B% U% l !<%`$ N $ 9 $ j $+$(
ruby_frame
$ B $ NA `: n $ KCmL \ $ 9 $ k !#$^$:$ ODj5A $ N $ H $ 3 $ m $ + $ i! #
struct FRAME frame;
FRAME
$ B $ K; j $ C $ F $ O9 = B $ BN $ ^ $ k $ 4 $ H% 9%?% C% /> e $ KCV
$ B $ $ $ F $ 7 $^$*$&$ H $$$&$ N $@!#< code> ruby $ B $,%^% 7% s% 9%?% C% / $ r% P %+?)$$$ 9 $ k $ N $ b $ 3 $&$$$&
$ B! V>. $ 5 $ J9) IW! W $, @ Q $ _ = E $ J $ C $? @ .2 L $ J $ N $ G $ "$ k! #
frame = * ruby_frame; / * $ B9 = B $ BN $ ^ $ k $ 4 $ H% 3% T! <* /
frame.tmp = ruby_frame; / * $ B85 $ NFRAME $ B $ rGC $ B $ + $ iJ] 8n $ 9 $ k * /
ruby_frame = &frame; / * ruby_frame $ B $ r: 9 $ 7BX $ ($ k * /
$ B! '
$ B! '
ruby_frame = frame.tmp; / * $ BLa $ 9 * /
ruby_frame
$ B $ r0l; ~ E * $ K: 9 $ 7BX $ ($ F $ $ $ k! J% W% C% 7% e $ G $ O $ J $ $! K $ h $&$@!#$ I
$ B $ & $ 7 $ F $ 3 $ s $ J $ 3 $ H $ r $ 7 $ F $ $ $ k $ N $ @ $ m $ &! #
FRAME
$ B $ H $$$&$ N $ O! V% a% =% C% I8F $ S = P $ 7 $ G @ Q $ ^ $ l $ k! W $ H @ bL @ $ 7 $?$,!"$ h $ j87L) $ K
$ B8 @ $ & $ H! VRuby $ B% W% m% 0% i% `$ r last_func
$ B $ J $ I $ b $=$&$@!#
FRAME
$ B $ r @ Q $ ^ $ J $$$+$ H $$$&$ H ! "$ 3 $ 3 $ O FRAME
$ B $ r @ Q $ s $ G
$ B $$$$> l = j $ G $ O $ J $$$+$ i $ G $ "$ k! #; EAH $_$+$ i8 @ $ ($ PK \ Ev $ O FRAME
$ B $ r @ Q $_$?$$$ o $ 1
$ B $@$,!"< code> FRAME $ B $ r @ Q $ `$ HNc30 $, H / @ 8 $ 7 $? $ H $ - $ K% W% m% 0% i% `$ N% P% C% /% H% l! <% 9 $ K $ =
$ B $ l $, = P $ F $ 7 $^$&!#% P% C% /% H% l! <% 9 $ H $$$&$ N $ O
% Ruby t.rb
t.rb: 11: in `c ': some error occured (ArgumentError)
from t.rb: 7: in `b '
from t.rb: 3: in `a '
from t.rb: 14
$ B% a% =% C% I $ NDj5A
$ BD4::
def m (a, b, c)
nil
end
NODE_DEFN
nd_mid = 9617 (m)
nd_noex = 2 (NOEX_PRIVATE)
nd_defn:
NODE_SCOPE
nd_rval = (null)
nd_tbl = 5 [_ ~ a b c]
nd_next:
NODE_ARGS
nd_cnt = 3
nd_rest = -1
nd_opt = (null)
NODE_NIL
Nd_defn
$ B $ K $ O> o $ K NODE_SCOPE
$ B $, F ~ $ C $ F
$ B $ $ $ k $ h $&$@!#< code> NODE_SCOPE $ B $ H8 @ $ ($ P% b% 8% e! <% KJ8 $ N $ H $ 3 $ m $ G $ b8 + $? $ h $ & $ K% m! <
$ B% +% kJQ? T% 9% 3! <% W $ r @ Q $`$?$ a $ N> pJs $ r3JG <$ 9 $ k% N! <% I $ G $ "$ k! #
NODE_DEFN
rb_eval ()
$ B $ N3: Ev% 3! <% I $ r8 + $ F $$$/!#%(% i! <= HM) $, $ d $? $ iB? $ / $ F
$ BLLE] $ @ $ C $? $ N $ G: F $ SA4It $ ^ $ H $ a $ F> JN, $ 7 $?! #
$ B $ = $ NJ) K! $ O $ $ $ D $ b $ HF1 $ 8 $ G $ "$ k! # B ($ A rb_raise () rb_warn () rb_warning ()
$ B $ r8F $ V
$ B $ @ $ 1 $ N $ b $ N !"$*$ h $ S4V @ \ E * $ K $ = $ l $ r8F $ V $ b $ N $ rA4It> C $ 7 $?! #
NODE * defn;
int noex;
if (SCOPE_TEST (SCOPE_PRIVATE) | | node-> nd_mid == init) (
noex = NOEX_PRIVATE; $ B! JA $ B! K
)
else if (SCOPE_TEST (SCOPE_PROTECTED)) (
noex = NOEX_PROTECTED; $ B! JB $ B! K
)
else if (ruby_class == rb_cObject) (
noex = node-> nd_noex; $ B! JC $ B! K
)
else (
noex = NOEX_PUBLIC; $ B! JD $ B! K
)
defn = copy_node_scope (node-> nd_defn, ruby_cref);
rb_add_method (ruby_class, node-> nd_mid, defn, noex);
result = Qnil;
private
$ B $ @ $ N protected
$ B $ @ $ N $ H $ $ $ & C18l $, = P $ F $ / $ k $ N $ G2D; k
$ B @-4X78 $ @ $ m $&!#% U% i% 0 $ NL> A0 $ K; H $ o $ l $ F $ $ $ k noex
$ B $ O < code> NOde EXposure $ B! J% N! <
$ B% I $ N2D; k @ -! K $ @ $ H; W $ o $ l $ k! # If
$ BJ8 $ N @ a $ r = gHV $ K8 + $ F $ $ $ 3 $ & #
SCOPE_TEST ()
$ B $ O scope_vmode
$ B $ K0z? T $ N% U% i% 0 $, N) $ C $ F $ $ $ k $ +3 NG '$ 9 $ k
$ B %^%/% m $ G $ "$ k !#=>$ C $ F $ 3 $ N> r7oJ8 $ NA0H> $ O! V private
$ B% 9% 3! < % W $ G $ "$ k $ +! W $ H
$ B $ $ $ & 0UL #$@!# 8eH> $ O! V initialize
$ B $ NDj5A $ J $ i private
$ B! W $ G $ "$ k !#%*% V% 8% '
$ B% /% H $ N = i4 | 2 = MQ% a% =% C% I initialize
$ B $ OLdEzL5MQ $ G private
$ B $ K $ J $ k $ N $ @! #
protected
$ B% 9% 3! <% W $ @ $ C $? $ I protected
$ B! J $ "$? $ j $^$(! K! #
Ruby $ B $ G $ O protected
$ B $ O $$$^$$$ A; H $ $ Public
$ B $ @! #
defn = copy_node_scope (node-> nd_defn, ruby_cref);
rb_add_method (ruby_class, node-> nd_mid, defn, noex);
copy_node_scope ()
$ B $ O% a% =% C% IK \ BN $ N @ hF, $ KIU $ $ $ F $ $ $ k
NODE_SCOPE
$ B! J $ @ $ 1! K $ r
$ B% 3% T! <$ 9 $ k4X? T $@!#< code> ruby_cref $ B $ rEO $ 7 $ F $ $ $ k $ H $ 3 $ m $,%]%$% s% H $ J $ N $ @
$ B $,! D! D> \ $ 7 $ / $ O $ 9 $ 08e $ G8 + $ F $$$/!#
rb_add_method ()
$ B $ GDI2C $ 9 $ l $ PDj5A $ O40N; $ G $ "$ k! #
$ BDj5A $ 9 $ k @ h $ O $ b $ A $ m $ s ruby_class
$ B $ @! #
copy_node_scope ()
copy_node_scope ()
$ B $ O rb_eval ()
$ B $ N% a% =% C% IDj5A! J NODE_DEFN
$ B! K $ H
$ BFC0 [% a% =% C% IDj5A! J NODE_DEFS
$ B! K $ @ $ 1 $ + $ i8F $ P $ l $ k $ N $ G !"$=$ NFs% v = j $ @ $ 1
$ B8 + $ l $ P; H $ o $ l $+$?$ rFCDj $ G $ - $ k !#$=$ 7 $ F $ = $ NFs% v = j $ G $ N; H $$$+$ ? $ O $ [$ \
$ BF1 $ 8 $ @! #
1752 static NODE *
1753 copy_node_scope (node, rval)
1754 NODE * node;
1755 VALUE rval;
(1756
1757 NODE * copy = rb_node_newnode (NODE_SCOPE, 0, rval, node-> nd_next);
1758
1759 if (node-> nd_tbl) (
1760 copy-> nd_tbl = ALLOC_N (ID, node-> nd_tbl [0] +1);
1761 MEMCPY (copy-> nd_tbl, node-> nd_tbl, ID, node-> nd_tbl [0] +1);
1762)
1763 else (
1764 copy-> nd_tbl = 0;
1765)
1766 return copy;
1767)
(eval.c)
rval
$ B $ O% a% =% C% I $, Dj5A $ 5 $ l $?;~$ N% /% i% 9 $ N% M% 9 % H> pJs! J ruby_cref
$ B! K
$ B $ @ $ C $?!#< code> nd_rval $ B $ K%;% C% H $ 5 $ l $ k $ + $ i rval
$ B $ H $ $ $ & $ 3 $ H $ @ $ m $ &! #
if
$ BJ8 $ G $ O NODE_SCOPE
$ B $ N nd_tbl
$ B $ r% 3% T! < $ 7 $ F $ $ $ k! # $ D $ ^ $ j% m !<%+% k
$ BJQ? TL> $ N% F! <% V% k $ G $ "$ k! # ALLOC_N ()
$ B $ G +1 $ B $ 7 $ F $ $ $ k $ N $ O nd_tbl [0]
$ B $ NJ, $ b9g
$ B $ o $; $ F3NJ] $ 9 $ k $? $ A $ @! # BhFsIt $ G8 + $? $ H $ * $ j nd_tbl [0]
$ B $ K $ O% m !<%+% kJQ? t $ N
$ B? T $, F ~ $ C $ F $ * $ j !"$=$ l $ O $ D $ ^ $ j! V nd_tbl
$ B $ N Copy_node_scope ()
$ B $ O% a% =% C% IK \ BN $ N% X% C% @ $ G $" $ k NODE_SCOPE
$ B $ r
$ BJ # @ = $ 9 $ k !"$?$@$ 7 nd_rval
$ B $, DI2C $ G%;% C% H $ 5 $ l $ k !#$=$ 7 $ F $ = $ l $ O% /% i% 9 $ rDj5A
$ B $ 7 $? $ H $ - $ N ruby_cref
$ B! J% /% i% 9 $ N% M% 9% H> pJs! K $ G $ "$ k! # $ 3 $ N> pJs $ O8e $ GDj? T $ d
$ B% /% i% 9JQ? T $ N; 2> H $ N $ H $ - $ K; H $ o $ l $ k! #
rb_add_method ()
237 void
238 rb_add_method (klass, mid, node, noex)
239 VALUE klass;
240 ID mid;
241 NODE * node;
242 int noex;
243 (
244 NODE * body;
245
246 if (NIL_P (klass)) klass = rb_cObject;
247 if (ruby_safe_level> = 4 & &
(klass == rb_cObject | |! OBJ_TAINTED (klass))) (
248 rb_raise (rb_eSecurityError, "Insecure: can't define method");
249)
250 if (OBJ_FROZEN (klass)) rb_error_frozen ( "class / module");
251 rb_clear_cache_by_id (mid);
252 body = NEW_METHOD (node, noex);
253 st_insert (RCLASS (klass) -> m_tbl, mid, body);
254)
(eval.c)
NEW_METHOD ()
$ B $ O NODE
$ B $ r @ 8 @. $ 9 $ k %^%/% m $ @! #
rb_clear_cache_by_id ()
$ B $ O% a% =% C% I% -% c% C% 7% e $ rA `: n $ 9 $ k4X? t $ G $" $ k! #
$ B O! X% a% =% C% I! Y $ G @ bL @ $ 9 $ k! #
m_tbl
$ B $ K3JG <$ 5 $ l $ k9 = J8LZ $ r8 + $ F $ _ $ h $ &! #
$ B $ 3 $&$$$&$ H $ - $ N $? $ A $ KMQ0U $ 7 $ F $*$$$?
nodedump-method
\ footnote ( nodedump-method
$ B! ' nodedump
$ B $ KF1 :-!#< code> nodedump $ B $ OE: IUCD-ROM $ B $ N tools / nodedump.tar.gz
) $ B $ r
$ B; H $ &! #
% Ruby-e '
class C
def m (a)
puts "ok"
end
end
require "nodedump-method"
NodeDump.dump C,: m # $ B% /% i% 9C $ B $ N% a% =% C% Im $ B $ r% @% s% W $ 9 $ k
'
NODE_METHOD
nd_noex = 0 (NOEX_PUBLIC)
nd_cnt = 0
nd_body:
NODE_SCOPE
nd_rval = Object <- C
nd_tbl = 3 [_ ~ a]
nd_next:
NODE_ARGS
nd_cnt = 1
nd_rest = -1
nd_opt = (null)
U $ B2g & n S $ BprCx
** Unhandled **
NODE_SCOPE
$ B $, IU $ /! #
$ B $$$/$ D $+%@% s% W $ 7 $ F $_$?$ H $ 3 $ mC $ B $ GDj5A $ 7 $?% A% =% C% I $ K $ O NODE_SCOPE
$ B $ OIU $ $ $ F
$ B $ $ $ J $ + $ C $? $ N $ G! "$ 3 $ l $, Ruby $ B% l% Y% k $ GDj5A $ 7 $?% A% =% C% I $ N0u $ i $ 7 $ $ #
nd_tbl
$ B $ K% a% =% C% I $ N% Q% i% a! <%? JQ? TL>! J a
$ B! K $, EP> l $ 7
$ B $ F $ $ $ k! # 0JA0! "% Q% i% a! <%? JQ? T $ OIaDL $ N% m !<%+% kJQ? T $ HF1 $ 8 $ @ $ H8 @ $ C $?$,!"$=
$ B $ l $, $ 3 $ 3 $ KC NODE_ARGS
$ B $ K $ D $ $ $ F $ O O! X% a% =% C% I! Y $ G07 $ & $ N $ G> JN , #
NODE_METHOD
$ B $ N nd_cnt
$ B $@$,!"$ 3 $ l $ O: # 2s $ O $"$^$ j5 $ $ K $ 7 $ J $ /
$ B $ F $$$$!#< code> alias $ B $,$+$ i $ s $ @ $ H $ - $ K; H $ & $ b $ N $ @! #
$ BBeF ~ $ H; 2> H
$ B% m !<%+% kJQ? t
ruby_scope-> local_vars
$ B $,; X $ 9G [Ns $ G $ "$ k! # NODE_LVAR
$ B $ N% 3! <% I $ O $ 3 $ & $ J $ k! #
2975 case NODE_LVAR:
2976 if (ruby_scope-> local_vars == 0) (
2977 rb_bug ( "unexpected local variable");
2978)
2979 result = ruby_scope-> local_vars [node-> nd_cnt];
2980 break;
(eval.c)
node-> nd_cnt
is
Parser local_cnt ()
was value in return.
constant
full version
struct RClass
- iv_tbl
instance variable and variable with class registration
In that.
rb_const_get ()
, was not the only super class. I'm
It? It is constant talk about the hidden spoken about the final version
The must-have. Look at the following code.
class A
C = 5
def A.new
puts C
super
end
end
A.new
is A
belonging to the specific method of class-specific classes are (A)
.
So if you interpret the rules as A
belong to a constant C
is not to win.
C
want to see it's only natural.
Ruby is therefore also refer to this. These specifications are "SOSUKO
I looked for the de-emphasize "reflects the character of Ruby be said.
rb_const_get ()
outside
The search path is no reason for class.
cbase
::
constant references are usually standing in the syntax tree NODE_CONST
said.
rb_eval ()
, said the code is……
2994 case NODE_CONST:
2995 result = ev_const_get (RNODE (ruby_frame-> cbase), node-> nd_vid, self);
2996 break;
(eval.c)
nd_vid
is Variable ID
a constant name. And ruby_frame-> cbase
is
"I wrote a method to define the location of the class." This is a method to start
Will be set when the code is still have not appeared in the set
Where the project is coming from, or even to say, this method is defined
copy_node_scope ()
, came nd_rval
for both sides. Come back and see a little head
If the thing, but this method is to define when a member of ruby_cref
will be
.
ruby_cref
links to
Formed. Now a defined class C
and out (Fig. 81).
m
to define and (probably C # m
),
Then ruby_cref
method is stored in the entry (Fig. 82).
ruby_cref
points to a different node, but will not,
node-> nd_rval
is of course continue the same points (Fig. 83).
C # m
is when you start node-> nd_rval
, retrieve,
Just loaded ruby_frame-> cbase
to Cart (Fig. 84).
Figure 8: CREF transfer
ev_const_get ()
NODE_CONST
back to the code.
The rest are ev_const_get ()
just to see it.
1550 static VALUE
1551 ev_const_get (cref, id, self)
1552 NODE * cref;
1553 ID id;
1554 VALUE self;
(1555
1556 NODE * cbase = cref;
1557 VALUE result;
1558
1559 while (cbase & & cbase-> nd_next) (
1560 VALUE klass = cbase-> nd_clss;
1561
1562 if (NIL_P (klass)) return rb_const_get (CLASS_OF (self), id);
1563 if (RCLASS (klass) -> iv_tbl & &
st_lookup (RCLASS (klass) -> iv_tbl, id, & result)) (
1564 return result;
1565)
1566 cbase = cbase-> nd_next;
1567)
1568 return rb_const_get (cref-> nd_clss, id);
1569)
(eval.c)
cref
, that is the original ruby_cref
, is NODE
of a linked list.
The list of the direct Tasoritsuku st_lookup ()
, iv_tbl
to find out. Suu outside of class
調べないpar until the class because of their specifications, rb_const_get ()
does not.
klass
is nil
…… So when a top-level lights and other nesting
Because the class to determine the direction of the superclass. This is
rb_const_get ()
the first time.
self
is a starting point.
Really confusing.
class variable
ruby_cref
. However, of course, constant as the outside
And looking for the next class because they do not use the first one. Class variable
References node, NODE_CVAR
, let's take a look at the code.
2998 case NODE_CVAR:
2999 result = rb_cvar_get (cvar_cbase (), node-> nd_vid);
3000 break;
(eval.c)
cvar_cbase ()
What is it? cbase
and know where to look
ruby_frame-> cbase
and the relationship is going to happen, how different? Let's see.
1571 static VALUE
1572 cvar_cbase ()
(1573
1574 NODE * cref = RNODE (ruby_frame-> cbase);
1575
1576 while (cref & & cref-> nd_next & &
FL_TEST (cref-> nd_clss, FL_SINGLETON)) (
1577 cref = cref-> nd_next;
1578 if (! Cref-> nd_next) (
1579 rb_warn ( "class variable access from toplevel singleton method");
1580)
1581)
1582 return cref-> nd_clss;
1583)
(eval.c)
cbase
traced back to the picture.
This is following a number of measures added.
class C class C
@ @ cvar = 1 @ @ cvar = 1
class <
ruby_cref
values are different. Define a specific use
It is ruby_cref = (C)
and dismembered-specific methods, it is
ruby_cref = C
. This class is variable at the inconvenience it has changed.
C
path into the search, so no problem. The assignment of more method in the first place
This is unrelated to write.
multiple assignment
ruby
comprehensive understanding of the structure of the book, even though the Ruby programming
Advanced level, not too little thing you do not have no choice. So here
Multiple assignment, the fundamental structure and a very simple "many-to-many" if only to consider
Especially now.
a, b = 7, 8
NODE_MASGN
nd_head:
NODE_ARRAY [
0:
NODE_LASGN
nd_cnt = 2
nd_value:
1:
NODE_LASGN
nd_cnt = 3
nd_value:
]
nd_value:
NODE_REXPAND
nd_head:
NODE_ARRAY [
0:
NODE_LIT
nd_lit = 7: Fixnum
1:
NODE_LIT
nd_lit = 8: Fixnum
]
NODE_ARRAY
list,
The right side NODE_REXPAND
even know. REXPAND
is Right value EXPAND?
The nodes are doing or what to worry about it. Let's see.
2575 case NODE_REXPAND:
2576 result = avalue_to_svalue (rb_eval (self, node-> nd_head));
2577 break;
(eval.c)
avalue_to_svalue ()
ignore the good.
rb_eval ()
, NODE_ARRAY
is evaluated by the (literal array of nodes it is so)
Ruby's return to the array. So before you handle the left side are all evaluated by the right side
It's not. That is why the following can be.
a, b = b, a # write a single line variable swap
NODE_MASGN
also look at.
2923 case NODE_MASGN:
2924 result = massign (self, node, rb_eval (self, node-> nd_value), 0);
2925 break;
(eval.c)
massign ()
delegates.
massign ()
3917 static VALUE
3918 massign (self, node, val, pcall)
3919 VALUE self;
3920 NODE * node;
3921 VALUE val;
3922 int pcall;
(3923
(eval.c)
pcall
is Proc CALL
, means that this function is Proc
calls for the use of objects
We have to see if the host country. Proc
and other calls for the multiple assignment
Check the severity is somewhat different, so I ask them to check the flags of the
The reason. Naturally, the value is either 0 or 1 reason.
massign ()
number of calls, but I'd like to see, pcall = 0
. Resona
In the meantime it is pcall = 0
beat and decided to expand the variables are already a構わ
INO to be. That's because, pcall
it behaves like a subtle change to the argument
And the two have always read the scenario and thinking but also in very面倒く
And. Even if the actual function massign ()
is one thing, even when it is read
pcall = 0
and pcall = 1
if the two functions have thought that it is much easier to read.
pcall = 0
as shaving all of his削れるbelow.
static VALUE
massign (self, node, val / *, pcall = 0 * /)
VALUE self;
NODE * node;
VALUE val;
(
NODE * list;
long i = 0, len;
val = svalue_to_mvalue (val);
len = RARRAY (val) -> len;
list = node-> nd_head;
/ * (A) * /
for (i = 0; list & & i
val
value to the right side. Also svalue_to_mvalue ()
converted to a suspicious fire that the
We are mvalue_to_svalue ()
, this is svalue_to_mvalue ()
So, "I'm sure rejoined
It should be "considered. Therefore, both away at once. The next line
RARRAY ()
from using the right side of the value of Ruby Array
and I heard a
Feel frisky. Meanwhile the left side node-> nd_head
, means that local variables list
has been assigned to
Value. This list
also node ( NODE_ARRAY
).
assign ()
name of the street, one-on-one assignment of functions. Is no left-hand
Mode of expression that, for example NODE_IASGN
(Variable instance)
And rb_ivar_set ()
in the assignment, so I do. Ie,
list
and val
it to meet one-on-one short of the assignment
(Fig. 9).
Figure 9: response to the assignment
node-> nd_args
(of expression
To the left side) assignment.
nil
is assigned.
pcall = 0
to cut back on the work of compiler optimization phase
Use data-flow analysis / convolution and the constant look-alike. That is automated to some extent
I think you can.
Translations,  additions,  and graphics by C.E. Thornton
This work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike2.5 License.