赞 54  
 
VIP 0 
 
好人卡 3 
 
积分 46  
 
经验 31992 
 
最后登录 2025-10-29 
 
在线时间 1206 小时 
 
 
 
Lv3.寻梦者 
	梦石 0   
        星屑 4603  
        在线时间 1206 小时 
        注册时间 2016-4-7 
        帖子 982  
 
 
 
	
 本帖最后由 shitake 于 2018-1-30 21:09 编辑   
 
rb_define_global_function( "srand" , rb_f_srand, -1 ) ;
    rb_define_global_function( "rand" , rb_f_rand, -1 ) ;
 
    rb_cRandom = rb_define_class( "Random" , rb_cObject) ;
    rb_define_alloc_func( rb_cRandom, random_alloc) ;
    rb_define_method( rb_cRandom, "initialize" , random_init, -1 ) ;
    rb_define_method( rb_cRandom, "rand" , random_rand, -1 ) ;
rb_define_global_function( "srand" , rb_f_srand, -1 ) ;
 
    rb_define_global_function( "rand" , rb_f_rand, -1 ) ;
 
 
 
    rb_cRandom = rb_define_class( "Random" , rb_cObject) ;
 
    rb_define_alloc_func( rb_cRandom, random_alloc) ;
 
    rb_define_method( rb_cRandom, "initialize" , random_init, -1 ) ;
 
    rb_define_method( rb_cRandom, "rand" , random_rand, -1 ) ;
 
 
这是ruby 的random.c里最后定义Random这个类的时候的代码 
 
其中rb_define_global_function("rand", rb_f_rand, -1); 复制代码  这句就是定义了Kernel的rand函数 
而这个rb_f_rand 长这样: 
static  VALUE
rb_f_rand( int  argc, VALUE *argv, VALUE obj) 
{ 
    VALUE vmax;
    rb_random_t *rnd = rand_start( &default_rand) ;
 
    if  ( rb_check_arity( argc, 0 , 1 )  && !NIL_P( vmax = argv[ 0 ] ) )  { 
        VALUE v = rand_range( Qnil, rnd, vmax) ;
        if  ( v != Qfalse)  return  v;
        vmax = rb_to_int( vmax) ;
        if  ( vmax != INT2FIX( 0 ) )  { 
            v = rand_int( Qnil, rnd, vmax, 0 ) ;
            if  ( !NIL_P( v) )  return  v;
        } 
    } 
    return  DBL2NUM( genrand_real( &rnd->mt) ) ;
} 
static  VALUE
 
rb_f_rand( int  argc, VALUE *argv, VALUE obj) 
 
{ 
 
    VALUE vmax;
 
    rb_random_t *rnd = rand_start( &default_rand) ;
 
 
 
    if  ( rb_check_arity( argc, 0 , 1 )  && !NIL_P( vmax = argv[ 0 ] ) )  { 
 
        VALUE v = rand_range( Qnil, rnd, vmax) ;
 
        if  ( v != Qfalse)  return  v;
 
        vmax = rb_to_int( vmax) ;
 
        if  ( vmax != INT2FIX( 0 ) )  { 
 
            v = rand_int( Qnil, rnd, vmax, 0 ) ;
 
            if  ( !NIL_P( v) )  return  v;
 
        } 
 
    } 
 
    return  DBL2NUM( genrand_real( &rnd->mt) ) ;
 
} 
 
 
 
而rb_define_method(rb_cRandom, "rand", random_rand, -1);  复制代码  这句就是在定义Random.rand了 
random_rand长这样: 
static  VALUE
random_rand( int  argc, VALUE *argv, VALUE obj) 
{ 
    VALUE v = rand_random( argc, argv, obj, get_rnd( obj) ) ;
    check_random_number( v, argv) ;
    return  v;
} 
 
static  VALUE
rand_random( int  argc, VALUE *argv, VALUE obj, rb_random_t *rnd) 
{ 
    VALUE vmax, v;
 
    if  ( rb_check_arity( argc, 0 , 1 )  == 0 )  { 
        return  rb_float_new( random_real( obj, rnd, TRUE ) ) ;
    } 
    vmax = argv[ 0 ] ;
    if  ( NIL_P( vmax) )  return  Qnil;
    if  ( !RB_TYPE_P( vmax, T_FLOAT) )  { 
        v = rb_check_to_int( vmax) ;
        if  ( !NIL_P( v) )  return  rand_int( obj, rnd, v, 1 ) ;
    } 
    v = rb_check_to_float( vmax) ;
    if  ( !NIL_P( v) )  { 
        const  double  max = float_value( v) ;
        if  ( max < 0.0 )  { 
            return  Qnil;
        } 
        else  { 
            double  r = random_real( obj, rnd, TRUE ) ;
            if  ( max > 0.0 )  r *= max;
            return  rb_float_new( r) ;
            } 
    } 
    return  rand_range( obj, rnd, vmax) ;
} 
static  VALUE
 
random_rand( int  argc, VALUE *argv, VALUE obj) 
 
{ 
 
    VALUE v = rand_random( argc, argv, obj, get_rnd( obj) ) ;
 
    check_random_number( v, argv) ;
 
    return  v;
 
} 
 
 
 
static  VALUE
 
rand_random( int  argc, VALUE *argv, VALUE obj, rb_random_t *rnd) 
 
{ 
 
    VALUE vmax, v;
 
 
 
    if  ( rb_check_arity( argc, 0 , 1 )  == 0 )  { 
 
        return  rb_float_new( random_real( obj, rnd, TRUE ) ) ;
 
    } 
 
    vmax = argv[ 0 ] ;
 
    if  ( NIL_P( vmax) )  return  Qnil;
 
    if  ( !RB_TYPE_P( vmax, T_FLOAT) )  { 
 
        v = rb_check_to_int( vmax) ;
 
        if  ( !NIL_P( v) )  return  rand_int( obj, rnd, v, 1 ) ;
 
    } 
 
    v = rb_check_to_float( vmax) ;
 
    if  ( !NIL_P( v) )  { 
 
        const  double  max = float_value( v) ;
 
        if  ( max < 0.0 )  { 
 
            return  Qnil;
 
        } 
 
        else  { 
 
            double  r = random_real( obj, rnd, TRUE ) ;
 
            if  ( max > 0.0 )  r *= max;
 
            return  rb_float_new( r) ;
 
            } 
 
    } 
 
    return  rand_range( obj, rnd, vmax) ;
 
} 
 
 
 
很明显可以看出 Kernel的起始值直接通过 default_rand 获得,而Random的则是调用 get_rnd。 
 
 评分 
查看全部评分