accessors break "no state change outside the object"?

Z

zuzu

from a "functional in the small and OO in the large" and "don't cause
any state change in an object from outside that object itself"
perspective, i fail to understand the use of accessors (aka get/set
methods).

hence, http://c2.com/cgi/wiki?AccessorsAreEvil

ruby accessors are merely shortcuts for reading/writing @-scope values
in an object.
http://www.ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/accessors.html

however, to me this seems like breaking the object-functional elegance
of The Ruby Way.
again, it allows changing the state inside an object, from outside the object.

why not simply use methods as methods, as to pass in information to
retreive other information?
why create special syntax for initialization / object creation (.new)
that also isn't specified with the .initialize / .new method?

atm, accessors feel like an artifact from procedural/imperative OO.

what do you think?

(before anyone jumps on a .new vs. .initialize tangent, remember
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/4707 )

peace,
-z
 
F

Florian Gross

zuzu said:
ruby accessors are merely shortcuts for reading/writing @-scope values
in an object.
http://www.ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/accessors.html

As I understand it Ruby's accessors are just convenient ways of adding
something to the interface of your Object that does modify state
internally. (Without the interface part enforcing that.)

attr_accessor basically does this:

class Module
def attr_accessor(name)
define_method(name) do
instance_variable_get:)"@#{name}")
end
define_method:)"#{name}=") do |value|
instance_variable_set:)"@#{name}", value)
end
end
end

That is, attr_accessor :foo creates two methods foo() and foo=(). You
can also create those manually and they need not be related to an
instance variable at all so I don't think this breaks encapsulation.
why create special syntax for initialization / object creation (.new)
that also isn't specified with the .initialize / .new method?

I don't see how this is related, but .new / .initialize are *no* special
syntax.

Class#new is defined like this:

class Class
def new(*args, &block)
result = self.allocate
result.send:)initialize, *args, &block)
return result
end
end

Class#allocate is special of course, because it needs to construct an
Object. You can't easily do that manually. (It's possible when using
evil-ruby, but there's no real purpose in doing so.)

So basically I don't see where accessors or Class#new break Ruby's basic
principles. I think Ruby is very consistent here. But then again I might
just not be understanding your objections -- if so, please try to
explain them in more detail.
peace,
-z

Regards,
Florian Gross
 
Z

zuzu

As I understand it Ruby's accessors are just convenient ways of adding
something to the interface of your Object that does modify state
internally. (Without the interface part enforcing that.)

attr_accessor basically does this:

class Module
def attr_accessor(name)
define_method(name) do
instance_variable_get:)"@#{name}")
end
define_method:)"#{name}=") do |value|
instance_variable_set:)"@#{name}", value)
end
end
end

That is, attr_accessor :foo creates two methods foo() and foo=(). You
can also create those manually and they need not be related to an
instance variable at all so I don't think this breaks encapsulation.

hmm... ok.
I don't see how this is related, but .new / .initialize are *no* special
syntax.

i was thinking that commonly accessors were used to modify
object-local scope values in ways that seemed like initializing tasks,
but i now am rather sure i was mistaken. so nevermind this.
Class#new is defined like this:

class Class
def new(*args, &block)
result = self.allocate
result.send:)initialize, *args, &block)
return result
end
end

Class#allocate is special of course, because it needs to construct an
Object. You can't easily do that manually. (It's possible when using
evil-ruby, but there's no real purpose in doing so.)

So basically I don't see where accessors or Class#new break Ruby's basic
principles. I think Ruby is very consistent here. But then again I might
just not be understanding your objections -- if so, please try to
explain them in more detail.


Regards,
Florian Gross

thanks,
-z
 
J

James Britt

zuzu said:
from a "functional in the small and OO in the large" and "don't cause
any state change in an object from outside that object itself"
perspective, i fail to understand the use of accessors (aka get/set
methods).

hence, http://c2.com/cgi/wiki?AccessorsAreEvil

ruby accessors are merely shortcuts for reading/writing @-scope values
in an object.
http://www.ruby-doc.org/docs/ruby-doc-bundle/UsersGuide/rg/accessors.html

however, to me this seems like breaking the object-functional elegance
of The Ruby Way.
again, it allows changing the state inside an object, from outside the object.

why not simply use methods as methods, as to pass in information to
retreive other information?
why create special syntax for initialization / object creation (.new)
that also isn't specified with the .initialize / .new method?

atm, accessors feel like an artifact from procedural/imperative OO.

what do you think?

I tend to agree with this view, preferring to think of objects as things
that respond to messages; if a message happens to have a direct
correlation to an instance variable or a methods it is just a
coincidence; the client should not operate on any presumptions about
implementation.

Equating accessor methods with what in another language would a public
instance variable seems like a carry-over from other languages with a
different (and arguably less well defined) OO model than Ruby.

I find it confusing, for example, that rdoc will document certain
methods as 'attributes', rather than as, well, methods, simply because a
handy syntactic shortcut was used to create the methods. Anyone using
the code, and looking at the API docs, should not be encouraged to
consider implementation details. (At least not by default, which is
what happens if you only create the methods using attr_* methods.)

That said, I think I can see why, for modeling purposes, some people
prefer to think of real-life objects as being a combination of qualities
+ behavior. If I model, say, a car, then car.color and car.start_engine
are conceptually different.

But I'm not convinced these distinctions need be carried over or made
explicit in the language itself; any and all attributes should be the
internal, private concern of the object.

My initial understanding of the attr_reader, attr_writer, and
attr_accessors methods was that they created methods to access object
attributes; i.e., attributes == instance variable; attr_reader :foo
created a way to read the @foo attribute/instance variable.

It appears, though, that there was already a tradition among Rubyist of
referring to those methods created by the attr_* functions as the
attributes themselves. And "attributes" that did not refer to an
instance variable of the same name as the accessor methods were
considered "virtual" attributes, as if Ruby had any other kind.

I think this point of view complicates understanding the Ruby object
model, where the only access to an object's internal state is through
messages. It may mislead newcomers into thinking that Ruby allows
unfettered access to object variables, an idea which then has to be
unlearned later on.

So, while in fact Ruby does strictly enforce the "messages only" policy,
there is a terminology and culture that I feel encourages one to make
artificial distinctions. This may make things more comfortable for
people used to languages with a different object model, but I'm not sure
it's a good thing for Ruby. (I also believe I'm in the minority on this.)


James
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,014
Latest member
BiancaFix3

Latest Threads

Top