Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
Ruby 2.0 ÖÐÄ£¿éǰÖõÄʵÏÖ
 
×÷Õß ÑÔÎÞ²»¾¡£¬»ðÁú¹ûÈí¼þ    ·¢²¼ÓÚ 2014-07-15
  2770  次浏览      28
 

Ruby 2.0 Ϊģ¿éÌí¼ÓÁËÒ»¸ö Module#prepend ·½·¨£¬¸ù¾Ý API ÎĵµµÄÃèÊö£¬ËüÒÔÏà·´µÄ˳Ðò¶Ô²ÎÊýÖðÒ»µ÷Óà prepend_features ·½·¨¡£ºÍÄ£¿é°üº¬ÀàËÆ£¬»á°ÑÒ»¸öÄ£¿éµÄ׿ÏÈÁ´²åÈëµ½ÁíÒ»¸öÄ£¿éµÄ׿ÏÈÁ´ÖУ¬µ«¸úÄ£¿é°üº¬°Ñ׿ÏÈÁ´²åµ½¸ÃÄ£¿éÖ®ºó²»Ò»Ñù£¬Ëü»á°Ñ׿ÏÈÁ´²åµ½¸ÃÄ£¿é֮ǰ¡£ÎÒϲ»¶°ÑÕâ¸öÌØÐÔ½Ð×öÄ£¿éǰÖá£

ÏȾٸöÀý×ÓÀ´ËµÃ÷Ä£¿éǰÖõÄ×÷Ó㬲¢ºÍÄ£¿é°üº¬×÷Á˶Աȡ£ÔÚÕâ¸öÀý×ÓÖУ¬Àà C ǰÖÃÁËÄ£¿é A ºÍ B£»Àà D °üº¬ÁËÄ£¿é A ºÍ B¡£

module A
def foo; 'A' end
end
module B
def foo; 'B' end
end
class C
prepend A, B # Prepending is done by this line
def foo; 'C' end
end
class D
include A, B
def foo; 'D' end
end
C.ancestors # => [A, B, C, Object, Kernel, BasicObject]
D.ancestors # => [D, A, B, Object, Kernel, BasicObject]
C.new.foo # => 'A'
D.new.foo # => 'D'

µÚ 10 ÐУ¬ÎÒÃÇÔÚ C ÖÐǰÖÃÁËÄ£¿é A ºÍ B£¬ÕâÑù A ºÍ B ¾Í²åÈëµ½ C µÄ׿ÏÈÁ´ÖÐÁË¡£´Ó 21 ºÍ 22 ÐÐÖеÄ×¢ÊÍÖУ¬ÎÒÃÇ¿ÉÒÔ¿´µ½£¬ÔÚ C µÄ׿ÏÈÁ´ÖУ¬A ºÍ B λÓÚ C ֮ǰ¡£¶øÔÚ D µÄ׿ÏÈÁ´ÖУ¬A ºÍ B λÓÚ D Ö®ºó¡£

Õâ¾ÍÊÇΪʲôµÚ 24 ÐУ¬C.new.foo µÄ·µ»ØÖµÊÇ 'A'£¬ÒòΪģ¿é A ǰÖÃÓÚ C£¬Î»ÓÚ׿ÏÈÁ´µÄ×îÇ°Ãæ£¬·½·¨²éÕÒ»áÓÅÏÈÕÒµ½ A ÖÐµÄ foo ·½·¨¡£

ÎÒÃÇ¿´µ½ÁËÄ£¿éǰÖõÄÇ¿´óµÄÌØÐÔ£¬µ«ÒÉÎÊÒ²ËæÖ®¶øÀ´¡£×îÏÔ¶øÒ×¼ûµÄÎÊÌâÊÇ£¬C.ancestors Ϊʲô²»ÊÇ´ÓÀà C ¿ªÊ¼¡£Òª½â¿ªÕâ¸öÒÉÎÊ£¬Ê×ÏÈÓ¦¸ÃŪÇå³þ prepend ·½·¨¶¼×öÁËÄÄЩ¹¤×÷¡£ÎÒÃǸúµ½Ô´´úÂëÖÐȥһ̽¾¿¾¹£¬ÏÂÃæÊÇ prepend µÄĬÈÏʵÏÖ Module#prepend ¶ÔÓ¦µÄÔ´´úÂ룺

static VALUE
rb_mod_prepend(int argc, VALUE *argv, VALUE module)
{
int i;
ID id_prepend_features, id_prepended;
CONST_ID(id_prepend_features, "prepend_features");
CONST_ID(id_prepended, "prepended");
for (i = 0; i < argc; i++)
Check_Type(argv[i], T_MODULE);
while (argc--) {
rb_funcall(argv[argc], id_prepend_features, 1, module);
rb_funcall(argv[argc], id_prepended, 1, module);
}
return module;
}

¿ÉÒÔ¿´µ½£¬ËüµÄÐÐΪºÍ Module#include ·½·¨¼¸ºõÒ»Ñù£¬Ö»²»¹ý»Øµ÷µÄ·½·¨²»Ò»Ñù¡£ÕâÀËü»Øµ÷Á˲ÎÊýÄ£¿éµÄ prepend_features ·½·¨ºÍ prepended ·½·¨¡£Í¬Ñù£¬Module#prepend_features ²ÅÊÇÕæÕý¸É»îµÄµØ·½£¬ËùÒÔ¸ú½øÈ¥¿´¿´¡£

static VALUE
rb_mod_prepend_features(VALUE module, VALUE prepend)
{
switch (TYPE(prepend)) {
case T_CLASS:
case T_MODULE:
break;
default:
Check_Type(prepend, T_CLASS);
break;
}
rb_prepend_module(prepend, module);
return module;
}
¡¡¡¡Ëü×öÁËһЩÀàÐÍ·½ÃæµÄ¼ì²é£¬ È»ºó°Ñ¹¤×÷½»¸øÁË rb_prepend_module º¯Êý£¬ÎÒÃÇ¿´¿´ rb_prepend_module º¯Êý×öÁËʲô¡£
void
rb_prepend_module(VALUE klass, VALUE module)
{
void rb_vm_check_redefinition_by_prepend(VALUE klass);
VALUE origin;
int changed = 0;
rb_frozen_class_p(klass);
if (!OBJ_UNTRUSTED(klass)) {
rb_secure(4);
}
Check_Type(module, T_MODULE);
OBJ_INFECT(klass, module);
origin = RCLASS_ORIGIN(klass);
if (origin == klass) {
origin = class_alloc(T_ICLASS, klass);
RCLASS_SUPER(origin) = RCLASS_SUPER(klass);
RCLASS_SUPER(klass) = origin;
RCLASS_ORIGIN(klass) = origin;
RCLASS_M_TBL(origin) = RCLASS_M_TBL(klass);
RCLASS_M_TBL(klass) = st_init_numtable();
st_foreach(RCLASS_M_TBL(origin), move_refined_method,
(st_data_t) RCLASS_M_TBL(klass));
}
changed = include_modules_at(klass, klass, module);
if (changed < 0)
rb_raise(rb_eArgError, "cyclic prepend detected");
if (changed) {
rb_clear_cache();
rb_vm_check_redefinition_by_prepend(klass);
}
}

Õâ¸öº¯Êý×öÁËһЩ¹¤×÷£¬ÎÒÃÇÀ´·ÖÎöһϡ£Ç° 16 Ðж¼ÊÇÔÚ×öһЩÀàÐͼì²éµÈ¹¤×÷£¬ÎÒÃÇÌø¹ý¡£´ÓµÚ 17 ÐпªÊ¼·ÖÎö¡£

Ê×ÏÈ£¬ºê RCLASS_ORIGIN »ñÈ¡ klass µÄ origin ³ÉÔ±£¬²¢ÇÒ°ÑËüºÍ klass ±È½Ï¡£ÎÒÃDz»ÖªµÀ origin ×Ö¶ÎÓÐʲô×÷Óã¬ÎÒÃÇÏȼÙÉè²âÊÔÌõ¼þÎªÕæ£¬¼´ klass µÄ origin ³ÉÔ±Ö¸Ïò×ÔÉí¡£ÎÒÃÇÀ´·ÖÎöһϠif Óï¾äÖеÄÂß¼­£º

19 ÐÐΪ klass ´´½¨ÁËÒ»¸öеİüº¬À࣬ÎÒÃǰÑËü³ÆÎªÔ­Ê¼Àࣻ

20 ~ 21 ÐаÑд´½¨µÄ°üº¬Àà²åÈëµ½ klass ºÍ klass µÄ¸¸ÀàÖм䣻

22 Ðн« klass µÄ origin ³ÉÔ±Ö¸ÏòÁËÐÂÀࣻ

½ÓÏÂÀ´£¬23 ~ 24 ÐÐ°Ñ klass µÄ·½·¨±í×ªÒÆµ½ÐÂÀàÖУ¬²¢Çå¿Õ klass µÄ·½·¨±í£»

×îºó£¬25 ÐÐÓÖ°Ñ klass Ô­Ïȵķ½·¨±íÖÐµÄ Refined ·½·¨ÒÆÁË»ØÀ´¡£

·ÖÎöÍê if Óï¾ä£¬ÎÒÃǼÌÐøÇ°½ø£¬À´µ½µÚ 28 ÐС£µÈµÈ£¬ÄãºÃÏñ¿´µ½ÁËÊìϤµÄ¶«Î÷¡£Ã»´í£¬ÄǾÍÊÇ include_modules_at ·½·¨¡£ÔÚǰһƪÎÄÕÂÖУ¬ÎÒÃÇÌÖÂÛÁËÕâ¸öº¯Êý£¬ËüÓÃÀ´°üº¬Ä³¸öÄ£¿é¡£Äã¼òÖ±²»¸ÒÏàÐÅ×Ô¼ºµÄÑÛ¾¦£¬Ã÷Ã÷ÊÇÔÚǰÖÃÄ£¿é£¬ÔõôͻȻÓÖ±ä³É°üº¬Ä£¿éÁË£¿

Êǵģ¬Ã»´í£¬Ëü¾ÍÊÇÔÚ°üº¬Ä£¿é¡£±»°üº¬µÄÄ£¿éµÄ׿ÏÈÁ´²åÈëµ½ÁË klass ºÍ klass µÄԭʼÀàÖ®¼ä¡£ÓÉÓÚ klass ÄÚ²¿µÄ·½·¨±íÒѾ­×ªÒƵ½ÉÏÓεÄԭʼÀàÖУ¬ËùÒÔ²åÈëµÄλÖÃÕýºÃºÏÊÊ¡£Ruby ͨ¹ýÕâÖֱ任£¬ÇÉÃîµØ½«Ç°ÖÃÄ£¿éת»¯Îª°üº¬Ä£¿é£¬Ì«°ôÁË¡£

ÏÂÃæÕâ¸öͼÃèÊöÁËÎÄÕ¿ªÍ·µÄÄǸöÀý×ÓÖУ¬Àà C ÖÐ prepend A, B Óï¾äÖ´ÐÐǰºóµÄ״̬£º

¡¡+-----+      +--------+
¡¡¡¡Before: | C |----->| Object |
¡¡¡¡+-----+ +--------+
¡¡¡¡+--------------- klass ----------------+
¡¡¡¡| |
¡¡¡¡v |
¡¡¡¡+-----+ +-----+ +-----+ +-----+ +--------+
¡¡¡¡After: | C |----->| A |----->| B |----->| C' |+---->| Object |
¡¡¡¡+-----+ +-----+ +-----+ +-----+ +--------+
¡¡¡¡| ^
¡¡¡¡| |
¡¡¡¡+--------------- origin ---------------+

ÕýÈç֮ǰ·ÖÎöµÄÄÇÑù£¬C' ¾ÍÊÇÄǸöд´½¨µÄ°üº¬À࣬ËüÊÇ C µÄԭʼÀà¡£µ«Èç¹ûÊÇÕâÑùµÄ»°£¬»¹ÊÇÎÞ·¨½âÊÍ֮ǰµÄÒÉÎÊ£ºÎªÊ²Ã´ C.ancestors ²»ÊÇ´ÓÀà C ¿ªÊ¼£¿Òª¸ãÇå³þÕâ¸öÎÊÌ⣬ÎÒÃÇÀ´¿´¿´ C.ancestors ÊÇÈçºÎ¹¤×÷µÄ¡£

ÎÒÃÇÕÒµ½ÁË Module#ancestors µÄÔ´´úÂ룬Ëü¿´ÆðÀ´±È½Ï¼òµ¥£º

VALUE
rb_mod_ancestors(VALUE mod)
{
VALUE p, ary = rb_ary_new();
for (p = mod; p; p = RCLASS_SUPER(p)) {
if (FL_TEST(p, FL_SINGLETON))
continue;
if (BUILTIN_TYPE(p) == T_ICLASS) {
rb_ary_push(ary, RBASIC(p)->klass);
}
else if (p == RCLASS_ORIGIN(p)) {
rb_ary_push(ary, p);
}
}
return ary;
}

¸Ãº¯ÊýÊ×ÏÈ´´½¨ÁËÒ»¸öÊý×飬Ȼºó¶Ô±éÀúÄ£¿éµÄ׿ÏÈÁ´£¬¶Ôÿ¸ö׿ÏÈ£¬Èç¹ûÊǰüº¬Àà»òÕßԭʼÀàÖ¸Ïò×ÔÉí£¬¾Í·ÅÔÚ·µ»ØµÄÊý×éÀïÃæ¡£ÁíÍ⣬Ëü»¹»áÌø¹ýµ¥ÀýÀà¡£

ÖÁ´Ë£¬Ö®Ç°µÄÒÉÎÊÒ²µÃµ½Á˽âÊÍ£¬C.ancestors ²¢Ã»ÓÐ°Ñ C ×ÔÉí°üº¬½øÈ¥£¬ÒòΪËü¼È²»Êǰüº¬À࣬Ҳ²»ÊÇ origin Ö¸Ïò×ÔÉíµÄÀà¡£¶ø C.ancestors ·µ»ØµÄÊý×éÖÐµÄ C ÆäʵÊÇ C µÄԭʼÀ࣬ͬʱҲÊÇ C µÄ°üº¬À࣬ËùÒÔËü²ÅÓÐ C Õâ¸öÃû×Ö¡£

Ä£¿éǰÖÃÆäʵҲÊÇͨ¹ýÄ£¿é°üº¬À´Íê³ÉµÄ£¬Ö»²»¹ýÔÚ°üº¬Ö®Ç°×öÁËÒ»Ð©ÌØÊâ´¦Àí£º´´½¨ÁËÒ»¸öԭʼÀ࣬ȻºóÔÚԭʼÀà֮ǰ°üº¬Ä£¿é¡£µ«ÓÉÓÚԭʼÀàÒ²ÊÇÒ»¸ö°üº¬À࣬Òò´Ë±»Ç°ÖÃÄ£¿éµÄij¸ö׿ÏÈ¿ÉÄÜ»áÔ½¹ýԭʼÀ࣬±ÈÈçÏÂÃæÕâ¸öÀý×Ó£º

A = Module.new
module B
def bar; 'B' end
end
module C
include A, B
end
class D
include A
prepend C
def bar; 'D' end
end
D.new.bar # => 'D'

Àà D ÔÚǰÖÃÄ£¿é C ֮ǰ£¬°üº¬ÁËÄ£¿é A¡£ÏÂͼÖУ¬Ç°Á½¸öÊÇ D ǰÖÃÄ£¿é C ֮ǰ£¬D ºÍ C µÄ׿ÏÈÁ´£¬µÚÈý¸öÊÇ D ǰÖÃÄ£¿é C Ö®ºó£¬D µÄ׿ÏÈÁ´¡£

+---+    +---+    +--------+
¡¡¡¡| D |--->| A |--->| Object |
¡¡¡¡+---+ +---+ +--------+
¡¡¡¡+---+ +---+ +---+ +--------+
¡¡¡¡| C |--->| A |--->| B |--->| Object |
¡¡¡¡+---+ +---+ +---+ +--------+
¡¡¡¡|
¡¡¡¡+-----------------+ A ʹµÃ²åÈëµãÒÆµ½ÁË D' µÄºóÃæ
¡¡¡¡|
¡¡¡¡v
¡¡¡¡+---+ +---+ +---+ +---+ +---+ +--------+
¡¡¡¡| D |--->| C |--->| D'|--->| A |--->| B |+-->| Object |
¡¡¡¡+---+ +---+ +---+ +---+ +---+ +--------+

ÕýÈçͼÖбê×¢µÄÄÇÑù£¬Ä£¿é A µÄ´æÔÚʹµÃ²åÈëµãÒÆµ½ÁË D' µÄºóÃæ£¬ËùÒÔ B λÓÚ D' µÄºóÃæ¡£ËùÒÔ D.new.bar µÄÖµÊÇ 'D' ¶ø²»ÊÇ 'B'¡£

ÏÖÔÚ£¬ÎÒÃÇÀí½âÁËÄ£¿éǰÖÃÔÚ Ruby ÄÚ²¿ÊÇÈçºÎʵÏֵġ£Ä£¿éǰÖ÷dz£ÓÐÓã¬Ö»ÒªÃ÷°×ÁËËüÊÇÈçºÎ¹¤×÷µÄ£¬ÄãÒ»¶¨ÄÜÏëµ½ËüµÄÓÃÎäÖ®µØ¡£

   
2770 ´Îä¯ÀÀ       28
Ïà¹ØÎÄÕÂ

΢·þÎñ²âÊÔÖ®µ¥Ôª²âÊÔ
һƪͼÎÄ´øÄãÁ˽â°×ºÐ²âÊÔÓÃÀýÉè¼Æ·½·¨
È«ÃæµÄÖÊÁ¿±£ÕÏÌåϵ֮»Ø¹é²âÊÔ²ßÂÔ
È˹¤ÖÇÄÜ×Ô¶¯»¯²âÊÔ̽Ë÷
Ïà¹ØÎĵµ

×Ô¶¯»¯½Ó¿Ú²âÊÔʵ¼ù֮·
jenkins³ÖÐø¼¯³É²âÊÔ
ÐÔÄܲâÊÔÕï¶Ï·ÖÎöÓëÓÅ»¯
ÐÔÄܲâÊÔʵÀý
Ïà¹Ø¿Î³Ì

³ÖÐø¼¯³É²âÊÔ×î¼Ñʵ¼ù
×Ô¶¯»¯²âÊÔÌåϵ½¨ÉèÓë×î¼Ñʵ¼ù
²âÊԼܹ¹µÄ¹¹½¨ÓëÓ¦ÓÃʵ¼ù
DevOpsʱ´úµÄ²âÊÔ¼¼ÊõÓë×î¼Ñʵ¼ù
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]

LoadRunnerÐÔÄܲâÊÔ»ù´¡
Èí¼þ²âÊÔ½á¹û·ÖÎöºÍÖÊÁ¿±¨¸æ
ÃæÏò¶ÔÏóÈí¼þ²âÊÔ¼¼ÊõÑо¿
Éè¼Æ²âÊÔÓÃÀýµÄËÄÌõÔ­Ôò
¹¦ÄܲâÊÔÖйÊÕÏÄ£Ð͵Ľ¨Á¢
ÐÔÄܲâÊÔ×ÛÊö


ÐÔÄܲâÊÔ·½·¨Óë¼¼Êõ
²âÊÔ¹ý³ÌÓëÍŶӹÜÀí
LoadRunner½øÐÐÐÔÄܲâÊÔ
WEBÓ¦ÓõÄÈí¼þ²âÊÔ
ÊÖ»úÈí¼þ²âÊÔ
°×ºÐ²âÊÔ·½·¨Óë¼¼Êõ


ij²©²ÊÐÐÒµ Êý¾Ý¿â×Ô¶¯»¯²âÊÔ
IT·þÎñÉÌ Web°²È«²âÊÔ
IT·þÎñÉÌ ×Ô¶¯»¯²âÊÔ¿ò¼Ü
º£º½¹É·Ý µ¥Ôª²âÊÔ¡¢Öع¹
²âÊÔÐèÇó·ÖÎöÓë²âÊÔÓÃÀý·ÖÎö
»¥ÁªÍøweb²âÊÔ·½·¨Óëʵ¼ù
»ùÓÚSeleniumµÄWeb×Ô¶¯»¯²âÊÔ