RoR:“user || = User.new”的含义
可能重复:
什么|| =(或等于)在Ruby中意味着什么?
在互联网上,我在Ruby / Rails中看到了以下语法:
user ||= User.new
我是新手,我不能解析这个。 有人可以向我解释“|| =”运算符的作用吗?
如果user
已设置, User.new
执行任何操作,否则将分配新的User
对象(使用User.new
创建)。
根据 “The Well-Grounded Rubyist”的作者David A. Black的说法:
x || = y表示:x || x = y
区别在于,如果x未定义,则x || = y不会抱怨,而如果键入x ||则不会抱怨 x = y并且范围内没有x,它会。
对于一些额外的细节,这里是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_OR
在node.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
,其中有趣的部分如下所示:
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中的赋值更多,但是看起来很有趣。
它基本上是一个快捷方式:
user = user || User.new
或者为了更好地理解:
if user.nil? user = User.new end
我打赌你以前见过类似的符号,比如’+’这样的运算符
i += 1
也可以写成:
i = i + 1
这个陈述相当于
user = user || User.new
相当于
user = user ? user : User.new
当且仅当user
为nil时,它才会将User.new
的值User.new
变量user
。 如果不是,则user
的内容将保持不变。
它等同于user = user || User.new
user = user || User.new
。
这取决于||
的短路行为 运营商。 如果表达式的左侧为真,那么右侧将是什么并不重要,整体表达式将为真,因此操作员“短路”并停止评估。 而不是返回布尔“真”, ||
operator返回它评估的最后一个值。
因此, ||=
对于分配默认值很有用。 如果user
有值,则user || User.new
user || User.new
计算到user
否则它将评估为User.new
,这是默认值。
等效块将是:
if user user = user else user = User.new end
该语句将user
设置为自身(如果它已经是现有对象)或User.new
(如果用户为null,则将创建新用户)。 这是一个逻辑OR,可以避免分配空的用户对象。
代码是一个简写
user = user || User.new
如果user为null,则user将设置为User.new
。
- rails – 如何使用祖先制作嵌套路由
- Rails在form_for中更改提交的路由
- peatio:database.yml的默认密码是什么?
- 头部使用未知选项-1 / -n错误。 可能与ruby有关
- ActiveRecord :: Enum – PG :: InvalidTextRepresentation:ERROR:整数的输入语法无效:
- 我可以使用Selenium IDE生成Cucumber / Capybara步骤吗?
- 创建自定义Rails记录器
- Geocoder Gem – 获取request.location.country的“保留”(即使在Local!中)
- Ruby的to_s方法问题(来自Axe第2版)