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!