Although I've 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 the attribute methods.
So here's how it works. I'll demonstrate on 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's calling the rb_attr
function for each argument. (I'm guessing argc
stands for argument counter
.) So we have to look at the rb_attr
source to understand how this 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's not relevant for this explanation */
}
As you can see, the interpreter checks if the access level is NOEX_PRIVATE
and raises errors if it is.