在某些情况下,红宝石的空白是否敏感?

时间:2018-05-26 14:04:49

标签: ruby syntax

单个空格会影响*返回的值:

rand * 10 #=> 2.7177010707339146
rand *10  #=> 1

我尝试使用Ripper来检查这两个表达式产生的标记。

Ripper.lex 'rand *10'
#=> [[[1, 0], :on_ident, "rand", EXPR_CMDARG],
#   [[1, 4], :on_sp, " ", EXPR_CMDARG],
#   [[1, 5], :on_op, "*", EXPR_BEG],
#   [[1, 6], :on_int, "10", EXPR_END|EXPR_ENDARG]]
Ripper.lex 'rand * 10'
#=> [[[1, 0], :on_ident, "rand", EXPR_CMDARG],
#   [[1, 4], :on_sp, " ", EXPR_CMDARG],
#   [[1, 5], :on_op, "*", EXPR_BEG],
#   [[1, 6], :on_sp, " ", EXPR_BEG],
#   [[1, 7], :on_int, "10", EXPR_END|EXPR_ENDARG]]

除了第二到第四个元素,我看不出任何差异。我认为右边的常量会以某种方式改变。

现在使用sexp

Ripper.sexp 'rand *10'
#=> [:program,
# [[:command,
#   [:@ident, "rand", [1, 0]],
#   [:args_add_block, [:args_add_star, [], [:@int, "10", [1, 6]]], false]]]]
Ripper.sexp 'rand * 10'
#=> [:program,
# [[:binary, [:vcall, [:@ident, "rand", [1, 0]]], :*, [:@int, "10", [1, 7]]]]]

可以看出存在很大差异。

如何以及为什么表达式会返回不同的值?

1 个答案:

答案 0 :(得分:3)

*中的*10unary splat operator,而* 10中的rand *10是可覆盖的二元运算符(在这种情况下解析为Float#*)。我们也可以从AST中看到,添加括号,表达式的等价是:

  • rand(*10)rand(10)相同,与rand * 10相同。
  • (rand) * (10)rand.*(10)相同,与def args(*args); p args; end args *10 # prints [10] args * 10 # prints [] 相同。

这也可以在运行时确认:

    // Native conditional tag only works on page load. Data update needs $conditional_tags data
    $is_front_page = et_fb_conditional_tag( 'is_front_page', $conditional_tags );
    $is_search     = et_fb_conditional_tag( 'is_search', $conditional_tags );
    $offset_number = 3;

    // Prepare query arguments
    $query_args    = array(
        'posts_per_page' => (int) $args['posts_number'],
        'post_type'      => 'project',
        'post_status'    => 'publish',
    );

    // Conditionally get paged data
    if ( defined( 'DOING_AJAX' ) && isset( $current_page[ 'paged'] ) ) {
        $et_paged = intval( $current_page[ 'paged' ] );
    } else {
        $et_paged = $is_front_page ? get_query_var( 'page' ) : get_query_var( 'paged' );
        $query_args['offset'] = ( ( $paged - 1 ) * intval( $posts_number ) ) + intval( $offset_number );
    }