dB'*_*dB' 0 ruby ruby-on-rails
可能重复:
Ruby中的|| =(或等于)是什么意思?
在互联网上,我在Ruby/Rails中看到了以下语法:
user ||= User.new
Run Code Online (Sandbox Code Playgroud)
我是新手,我无法解析这个问题.有人可以向我解释"|| ="运算符的作用吗?
如果user已设置,则不执行任何操作,否则将分配新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));
}
}
Run Code Online (Sandbox Code Playgroud)
NEW_OP_ASGN_OR定义node.h如下:
#define NEW_OP_ASGN_OR(i,val) NEW_NODE(NODE_OP_ASGN_OR,i,val,0)
Run Code Online (Sandbox Code Playgroud)
NEW_NODE 看起来像这样:
#define NEW_NODE(t,a0,a1,a2) rb_node_newnode((t),(VALUE)(a0),(VALUE)(a1),(VALUE)(a2))
Run Code Online (Sandbox Code Playgroud)
寻找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;
}
Run Code Online (Sandbox Code Playgroud)
我认为这比我想知道的Ruby中的赋值更多,但是看起来很有趣.