RoR:“user ||= User.new"的含义; [英] RoR: Meaning of "user ||= User.new"

查看:32
本文介绍了RoR:“user ||= User.new"的含义;的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能的重复:
在 Ruby 中 ||=(或等于)是什么意思?

在互联网上我看过Ruby/Rails 中的以下语法:

Out on the internet I've seen the following syntax in Ruby/Rails:

user ||= User.new

我是新手,无法解析.有人可以向我解释||="运算符的作用吗?

I'm a newbie and I can't parse this. Can someone explain to me what the "||=" operator does?

推荐答案

如果 user 已经被设置,这什么都不做,否则它会分配一个新的 User 对象(创建使用 User.new).

If user is already set this does nothing, otherwise it will assign a new User object (created with User.new).

据大卫 A. Black,《The Well-Grounded Rubyist》的作者:

According to David A. Black, author of "The Well-Grounded Rubyist":

x ||= y 表示:x ||x = y

x ||= y means: x || x = y

区别在于 x ||= y 如果 x 未定义,则不会报错,而如果你输入 x ||x = y 并且范围内没有 x,它会.

The difference is that x ||= y won't complain if x is undefined, whereas if you type x || x = y and there's no x in scope, it will.

对于一些附加的细节,这里是 parse.y:

For some added details, here's the relevant part of parse.y:

| var_lhs tOP_ASGN command_call
{
  /*%%%*/
  value_expr($3);
  if ($1) {
    ID vid = $1->nd_vid;
    if ($2 == tOROP) {
      $1->nd_value = $3;
      $$ = NEW_OP_ASGN_OR(gettable(vid), $1);
      if (is_asgn_or_id(vid)) {
        $$->nd_aid = vid;
      }
    }
    else if ($2 == tANDOP) {
      $1->nd_value = $3;
      $$ = NEW_OP_ASGN_AND(gettable(vid), $1);
    }
    else {
      $$ = $1;
      $$->nd_value = NEW_CALL(gettable(vid), $2, NEW_LIST($3));
    }
  }

NEW_OP_ASGN_ORnode.h 中定义:

#define NEW_OP_ASGN_OR(i,val) NEW_NODE(NODE_OP_ASGN_OR,i,val,0)

NEW_NODE 看起来像这样:

#define NEW_NODE(t,a0,a1,a2) rb_node_newnode((t),(VALUE)(a0),(VALUE)(a1),(VALUE)(a2))

寻找NODE_OP_ASGN_OR 导致compile.c,其中有趣的部分如下所示:

Looking for NODE_OP_ASGN_OR leads to compile.c, where the interesting part looks like this:

case NODE_OP_ASGN_OR:{
   LABEL *lfin = NEW_LABEL(nd_line(node));
   LABEL *lassign;

   if (nd_type(node) == NODE_OP_ASGN_OR) {
     LABEL *lfinish[2];
     lfinish[0] = lfin;
     lfinish[1] = 0;
     defined_expr(iseq, ret, node->nd_head, lfinish, Qfalse);
     lassign = lfinish[1];
     if (!lassign) {
       lassign = NEW_LABEL(nd_line(node));
     }
     ADD_INSNL(ret, nd_line(node), branchunless, lassign);
   }
   else {
     lassign = NEW_LABEL(nd_line(node));
   }

   COMPILE(ret, "NODE_OP_ASGN_AND/OR#nd_head", node->nd_head);
   ADD_INSN(ret, nd_line(node), dup);

   if (nd_type(node) == NODE_OP_ASGN_AND) {
     ADD_INSNL(ret, nd_line(node), branchunless, lfin);
   }
   else {
     ADD_INSNL(ret, nd_line(node), branchif, lfin);
   }

   ADD_INSN(ret, nd_line(node), pop);
   ADD_LABEL(ret, lassign);
   COMPILE(ret, "NODE_OP_ASGN_AND/OR#nd_value", node->nd_value);
   ADD_LABEL(ret, lfin);

   if (poped) {
     /* we can apply more optimize */
     ADD_INSN(ret, nd_line(node), pop);
   }
   break;
 }

我认为这比我想知道的关于 Ruby 中的赋值要多得多,但查阅它还是很有趣的.

I think this is more than I ever wanted to know about assignment in Ruby, but it was rather entertaining to look this up.

这篇关于RoR:“user ||= User.new"的含义;的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆