what is the self for? I thought it might be an accessor
It's a method at least - probably an accessor. self.name = something will call the method name= and self.name, or if no local variable called name exists, just name will call the method name.
but then can't it be just user_name instead of self.user_name?
When invoking the name= method you need the self because name = something would just create a local variable called name. When invoking the name method, it doesn't matter whether you write name or self.name unless there is also a local variable called name.
And I don't even see any code to make it an accessor, like attr_accessor, and not in the base class either.
If there is no call to attr_accessor and no explicit definition of name and name= anywhere, they might be handled by method_missing or defined by a different method than attr_accessor.
isn't self.user_name the same as @user_name
Only if it's defined to be. If you define user_name and user_name=? usingattr_accessorthey will get and set@user_name`. However if you define them through other means (or manually), they can do whatever you want.
For example ActiveRecord uses method_missing to "define" getter and setter methods that correspond to data base columns. So if your ActiveRecord class belongs to a table with a user_name column, you'll have user_name and user_name= methods without defining them anywhere. The values returned by user_name and set by user_name = will also not correspond to instance variables. I.e. there will be no instance variable named @user_name.
Another way to automatically define user_name and user_name= without using instance variables is Struct:
MyClass = Struct.new(:user_name)
Here MyClass will have the methods user_name and user_name=, but no instance variable @user_name will be set at any point.