クラスの例を見てみましょう:
# in ./example.rb
class Example
private
attr_accessor :name
end
詳細モードで実行すると、Ruby から警告が表示されます。
$ ruby -W2 ./example.rb
example.rb:3: warning: private attribute?
これが推奨されないのはなぜですか?
クラスの例を見てみましょう:
# in ./example.rb
class Example
private
attr_accessor :name
end
詳細モードで実行すると、Ruby から警告が表示されます。
$ ruby -W2 ./example.rb
example.rb:3: warning: private attribute?
これが推奨されないのはなぜですか?
@paddeの回答を受け入れましたが、今後の参考のためにいくつかのコードを共有したいと思います。
属性メソッドのデフォルトのアクセスレベルに関する@Babaiの回答を確認したかったのです。
これがどのように機能するかです。のソースでデモンストレーションします2.0.0-p247
。
これはのソースですattr_accessor
:
static VALUE
rb_mod_attr_accessor(int argc, VALUE *argv, VALUE klass)
{
int i;
for (i=0; i<argc; i++) {
rb_attr(klass, rb_to_id(argv[i]), TRUE, TRUE, TRUE);
}
return Qnil;
}
ご覧のとおりrb_attr
、各引数に対して関数を呼び出しています。argc
( はの略だと思いargument counter
ます。) したがって、rb_attr
これがどのように機能するかを理解するには、ソースを確認する必要があります。
void
rb_attr(VALUE klass, ID id, int read, int write, int ex)
{
const char *name;
ID attriv;
VALUE aname;
rb_method_flag_t noex;
if (!ex) {
noex = NOEX_PUBLIC;
}
else {
if (SCOPE_TEST(NOEX_PRIVATE)) {
noex = NOEX_PRIVATE;
rb_warning((SCOPE_CHECK(NOEX_MODFUNC)) ?
"attribute accessor as module_function" :
"private attribute?");
}
else if (SCOPE_TEST(NOEX_PROTECTED)) {
noex = NOEX_PROTECTED;
}
else {
noex = NOEX_PUBLIC;
}
}
/* more logic that's not relevant for this explanation */
}
ご覧のとおり、インタープリターはアクセス レベルがNOEX_PRIVATE
であるかどうかをチェックし、そうである場合はエラーを発生させます。