重複の可能性:
Rubyで|| =(または等しい)とはどういう意味ですか?
インターネット上で、Ruby/Railsで次の構文を見ました。
user ||= User.new
私は初心者で、これを解析することはできません。「||=」演算子の機能を誰かに説明してもらえますか?
重複の可能性:
Rubyで|| =(または等しい)とはどういう意味ですか?
インターネット上で、Ruby/Railsで次の構文を見ました。
user ||= User.new
私は初心者で、これを解析することはできません。「||=」演算子の機能を誰かに説明してもらえますか?
がすでに設定されている場合、これは何もしません。そうでない場合は、新しいオブジェクト(で作成された)user
を割り当てます。User
User.new
「TheWell-GroundedRubyist」の著者であるデビッド・A・ブラックによると、
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
がnilの場合にのみ、の値をUser.new
変数に割り当てます。そうでない場合、の内容は変更されません。user
user
user
と同等user = user || User.new
です。
||
これは、オペレーターの短絡動作に依存しています。式の左側がtrueの場合、右側が何であるかは関係ありません。式全体がtrueになるため、演算子は「短絡」して評価を停止します。また、ブール値の「true」を返すのではなく、||
演算子は評価した最後の値を返します。
したがって、||=
デフォルト値を割り当てるのに役立ちます。に値がある場合user
は、にuser || User.new
評価されます。user
それ以外の場合User.new
は、デフォルト値に評価されます。
同等のブロックは次のようになります。
if user
user = user
else
user = User.new
end
ステートメントuser
はそれ自体に設定されます(既存のオブジェクトの場合)またはUser.new
(ユーザーがnullの場合は新しいユーザーを作成します)。これは、nullユーザーオブジェクトが割り当てられないようにする論理ORです。
コードはの省略形です
user = user || User.new
userがnullの場合、userはに設定されUser.new
ます。