Ruby User Group??
Rob Wehrli
plug-devel@lists.PLUG.phoenix.az.us
Thu Mar 21 09:31:25 2002
On Thursday, March 21, 2002 12:08 AM, Carl Parrish [SMTP:cparrish@cox.net]
wrote:
>
>
> Ops sorry. But again why I think we need an "offical" language. @name =
> name says to make a instance varible called name and give it the value
> of the local varible name. Once I got used to it I like this format
> because just by looking at it I know that @name is a instance varable,
> without having to know anything else about the code. @@ in front would
> have been a Class varible and $ would have been a global. And if it
> starts with a Capital letter then its a constant
>
Coding conventions are interesting areas for discussion, but syntactic
requirements are mechanisms used to faciliate the functional requirements
of the language.
>
> Here they are:
>
>
> each is not really a "keyword", actually almost everything in Ruby can
> be overloaded so there really doesn't seem to *be* many "keywords".
> However it is a default method of Array and used pretty commond so it
> work's like a keyword. And I think that's why Forms extended Array (just
> so he could get the "each" method). Ruby coders seem to prefer this
Screeeeeching HALT. Inheritance for behavior isn't "bad" except when
something is CLEARLY not a kind of what it is derived from. A Form, or
anything that we think of as a "real world" form, is NOT A KIND of an
Array. If that were somehow true, you could simply use a Form anywhere
that you'd use an Array. And, that should be the litmus test for
determining whether a derived class is, in fact, properly derived (should
inherit from). This is what I commonly talk about as being a Bird is not a
Rock inheritance argument and, eventually, "avoidance" problem.
Birds use Rocks. They (in real life) swallow little bits of rocks such
that they get stuck in their gizzards and can subsequently grind up their
food. In your "behavoir" example where Form is a kind of an Array, a Bird
is a kind of a Rock so that Bird can get at Rock's attributes and
operations. I think that we can clearly say that a Bird should not be a
kind of a Rock.
The goal of OO is to model (at least more closely) real life "objects."
The design of an object hierarchy should be "sensible" in that you
wouldn't find the definition of Bird inside of a Rock object and vice
versa. Where a Bird object requires a Rock "service provider"
relationship, a simple interface and instantiation designation appears
suitable for the task. Generally, since Bird uses Rock, Bird instantiates
(aggregation, also called composition) Rock(s) and uses the Rock's public
interfaces to obtain Rock-offered services. As good OO programmers, we
don't make a Bird a kind of Rock so that we can easily have Rock's
attributes and operations inside of Bird.
> method over for loops and now that I'm getting used to it (and code
> blocks, which work different in Ruby than in any other language I can
> think of) I can see that its both more powerful to use this syntax and
> easier to read. (however unlike python you can still do a for loop in
> the form I'm familar with). Also (form != forms.last()) does eval to a
> bool so I'm not really sure what you're talking about there.
>
This was an error on my part...at least in stating that the expression
would not evaluate to a boolean. (Remembering that != is a test for
inequality, helps) I think that I was "(nit)picking apart" the following:
Form form (unique class)
Forms < Array (different unique class, derived from type Array)
Form form = forms.first();
"=" is not an equality operator, but a *conversion* operator (must convert
from class Forms to class Form?!) in this case?! :)
Therefore, (form != forms.last()) is always true...unless, of course, the
conversion is implicit when testing for inequality!?
Do you see that the potential for confusion is not necessarily at all in
the syntax of the language, rather, in the CODE SAMPLE provided by the
obviously LACKING author of the LJ article. Now we have Birds that are
Rocks and implicit conversion before testing for inequality. Notably, in
the sample, the Java class instance representing the variable "forms" was
unspecified. The reader was only left with the Ruby specification of Forms
for contrast. Assumedly, the Java Forms class is in someway similar,
however, distinctly different than the Form class?! Crappy examples do
little more than add confusion, and poor inheritance choices, whether or
not convenient, are not good OOP.
>
> > for a class Form an array of Form objects becomes Form forms[]...which
> > is infinitely more OOP-correct than a Forms isa Array. I think that
the
> > LJ author wrote without a clue :) Way too many people really DO NOT
get
> > OO...but can use it just enough to be really dangerous...
> >
> True that, and I may be one of those people. However in this case the
> Class of Forms is really just a Collection of (I'm assuming) Form. So I
> don't really see a problem in his using an extend Array class to hold
> it.
Do you see the problem in extending Array yet? If Forms is a
specialization of Array simply to hold Form objects, the [] operator makes
much better sense.
Form[] forms
forms.first()
forms.last()
...etc.
The point is that you don't have a "new class" definition that is nothing
more than a convenience type, but a simple type "modifier" that allows any
class to be some number of instances of that class WITHOUT inheritence!
Form[] does not become Form < Array, but it has the same behavioral
aspects of a (inappropriately) derived implementation.
Otherwise, we're left with the following!
Forms < Array (A kind of Array called Forms, with or without any
specialization specification)
Form (unique class definition)
Forms.add( Form an_instance )
Forms.remove( Form an_instance )
Forms.add( Bug an_instance )
Forms.add( Rock an_instance )
Forms.add( Building an_instance )
...etc.
Forms is a simple "collection" class that has no requirement to store "F
orm" objects! Now maybe in real code you overload add() so that it must
take only a Form object, but I don't think that is really what is
happening! I think that the TYPE MANAGEMENT is strictly BY CONVENTION and
not facilitated by any hard rule that prevents "wrong" uses of the Forms
"collection." (I use double quotes because, whose to say that it really is
a collection of Forms and not Bugs, Rocks and/or Buildings?!)
>
> Well there are Modules (I think more like python's). and Namespaces
> though I admitt I don't quite understand them in Ruby yet.
I'm fairly certain that they are very important to understanding the "true"
power of Ruby...somewhere along the way, I think that you'll find that they
must at least enforce some rules that help keep the programmer from writing
more code :)
>
> class Name
> def initialization(name)
> @name = name
> end
> end
>
> in this case you have three "names" one Class one local paramiter (yes
> initialization is the constructor). and one instanstance varable. Since
The scoping of the "instance" versus "local" variables are a bit ambigous
to me, though I guess that the "name" passed in the initialization function
and the "class variable?" (dereferenced by?) @name isn't too hard to grasp.
The problem I'm having I guess is with "soft" typing. The only place in
our class specification above, which is obviously a trivial class of no
real value, that our "name" member (class attribute) is declared is in the
ctor, and can be any type. Of course, let's say that (for the sake of
argument) that we use this as follows:
class LastName < Name
def initialization(name)
@name = name
end
end
Does the same "name" used to initialize/construct LastName get passed in on
the initializer of the Name parent? ...since no "no args" default
constructor is declared or apparently implemented?
What happens when we say:
class LastName < Name
def some_function(xyz)
@abc = xyz
end
end
Where we don't have a "name" to initialize the parent?! Does Ruby
magically provide us with the initialization?
Also, is the "initialization()" method a "reserved" method for
construction? ...in that it is called automatically when instantiated?
The "def" looks like it could be either a "default" (therefore, do this
when instantiating) or simply "def(ine) ...this...block...whatever.... end"
>
> > And FINALLY (snicker)...in what language is the interpreter written? :)
> >
> And yes of course the interpreter is C
>
How's that for being the "official" language of Linux ;)
Take Care.
Rob!