Why Ruby throws warnings for private attributes

Take an example class:

# in ./example.rb class Example private attr_accessor :name end 

When I run it in verbose mode, Ruby throws me warnings:

 $ ruby -W2 ./example.rb example.rb:3: warning: private attribute? 

Why is this not recommended?

+6
source share
2 answers

Because it makes no sense to define a getter / setter, which in most cases is not visible from the outside. Usually we use attr_accessor only to set the instance variable outside the class. However, the private keyword hits this target, making the created getter / setter methods invisible to the outside world.

The only reason you want to use a private setter / receiver is when there is some additional logic. In this case, however, you will have to define these methods manually with def , anyway.

+3
source

Although I accepted @padde's answer, I would like to share some code for future reference.

I wanted to check @Babai's answer about the default access levels of attribute methods.

So how does it work. I will demonstrate the source from 2.0.0-p247 .

This is the source of 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; } 

As you can see, it calls the rb_attr function for each argument. (I assume argc means argument counter .) So, we should look at the source of rb_attr to understand how it all works:

 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 not relevant for this explanation */ } 

As you can see, the interpreter checks if the access level is NOEX_PRIVATE and throws errors, if any.

+1
source

Source: https://habr.com/ru/post/951998/


All Articles