The Third Ruby - Ever Comes Out at Night?

M

Mike Stephens

Often you see that Ruby can be object-oriented, functional or
procedural.

What would you expect to see in a program that made you say "Ah this is
procedural Ruby!"?
 
E

elise huard

I guess you could work only with modules and class methods, and avoid
instantiating any objects except Kernel, but it would be awfully ugly
and pointless exercise.
 
J

Jesús Gabriel y Galán

I guess you could work only with modules and class methods, and avoid
instantiating any objects except Kernel, but it would be awfully ugly
and pointless exercise.

As I understand it, you wouldn't use classes or modules at all. Only
top-level methods ("functions") and statements.
I use this style a lot for little utility scripts (I now use Ruby
instead of bash, generally, for these things).

Jesus.
 
E

elise huard

2010/10/2 Jes=FAs Gabriel y Gal=E1n said:
As I understand it, you wouldn't use classes or modules at all. Only
top-level methods ("functions") and statements.
I use this style a lot for little utility scripts (I now use Ruby
instead of bash, generally, for these things).

I guess. This top-level approach would only take you so far - though
it would do for short scripts, you're right.
I was thinking of C programs where external resources are 'included',
and modules by extensions could work like that.
 
M

Mike Stephens

I guess. This top-level approach would only take you so far .

Prior to the advent of OO, we used procedural styles, and we still had
to run 500-seat call centres, book planes, run multinational banks,
invent new drugs etc.

I guess applications that are database-oriented are easier to do
procedurally as you tend to use simple data structures (relations ->
arrays).

Trying to use procedural for some GUI visual design package would be
tough, but a lot of real applications (web sites, twitter etc) are just
reading and writing simple data structures.

The plus about procedural is it makes you partition. Just creating
objects doesn't necessarily add order and elegance to a system.
 
R

Robert Klemme

Prior to the advent of OO, we used procedural styles, and we still had
to run 500-seat call centres, book planes, run multinational banks,
invent new drugs etc.

Well, prior to automobiles people had to get from A to B, too. Ah, the
good old times. But then it took a week to travel 500km which we easily
do in one day today. Plus, we have heating in winter.
I guess applications that are database-oriented are easier to do
procedurally as you tend to use simple data structures (relations ->
arrays).

There is no reason why these "simple data structures" should not contain
functionality beyond setters and getters. I'm not even sure that your
statement about simpler data structures in DB oriented applications is
correct. Data models of even the simplest of ERP systems are quite
complex - and that doesn't even include SAP and Peopleware.
Trying to use procedural for some GUI visual design package would be
tough, but a lot of real applications (web sites, twitter etc) are just
reading and writing simple data structures.

The plus about procedural is it makes you partition. Just creating
objects doesn't necessarily add order and elegance to a system.

What you call "partitioning" is the core of software engineering:
separating concerns and distributing functionality across language
constructs is the most important thing we do - and we do it all the
time. OO gives you another dimension in which you can distribute
functionality. IMHO this is what makes it superior to procedural
programming - but also more difficult. I do not believe that procedural
programs are automatically better or worse than object oriented ones.

Btw, it is not easy to use Ruby procedural only. First, because
everything is an object, which means you cannot escape object
orientation. Second, even if you try to only write top level methods
and not use instance methods (which will at least make it look
procedural) you will have a hard time doing only the simplest of string
manipulations because the majority of that functionality sits in
instance methods of String (#gsub, #scan, #[] etc.).

Kind regards

robert
 
E

elise huard

Prior to the advent of OO, we used procedural styles, and we still had
to run 500-seat call centres, book planes, run multinational banks,
invent new drugs etc.

I think you misunderstood what I wanted to say (I wasn't very clear).
I meant that putting everything in one script will only take you so
far, at some point you'll need to split into other files, which is
where Modules might come in if you really wanted to avoid classes.
I've done plenty of C, so you won't hear me talk against procedural
especially, I'm not a fanatic of any paradigm.
 
E

elise huard

but before that, my main point was that trying to use Ruby
(specifically) in a procedural way would be silly, unless you can
prove otherwise.
 
M

Mike Stephens

It's beginning to firm up up in my mind.

OO treats data and methods as intertwined. An object has its data and
its methods. Procedural treats methods and data as two groups on each
side of the dance floor, changing partners as the night proceeds.

With procedural you can carry out data analysis and create a database
based on the qualities of the data rather than any consideration of what
methods are going to use them and in what way.

Similarly you can create a structure of procedures that describe how you
are going to address the task of the program, without at that point
considering data in any detail.

Eventually the procedures map onto the data structure but tend to share
'objects' with other procedures. I guess often you could group data and
procedures into 'classes' as they will have patterns of 'closed' usage,
but you don't have to.

On a separate tack, procedural doesn't hide methods (because it doesn't
have the language feature to do so) so a procedural program will trust
other programmers not to abuse code.
 
R

Robert Klemme

It's beginning to firm up up in my mind.

OO treats data and methods as intertwined. An object has its data and
its methods.

More importantly: they are connected! Methods work on an instance's
state, read and update it. By encapsulating state you gain added
robustness because by maintaining a class invariant your objects are
always in a valid state. Anybody (including procedures) can change
elements of a structure in arbitrary ways, which is much less robust.
Procedural treats methods and data as two groups on each
side of the dance floor, changing partners as the night proceeds.

But you cannot apply a procedure on arbitrary data. Input and output
types need to fit the data at hand.
With procedural you can carry out data analysis and create a database
based on the qualities of the data rather than any consideration of what
methods are going to use them and in what way.

Hm... I don't think people write database schemas without any thought
to the intended usage. And that intended usage also manifests in the
constraints which are placed in the schema. Illegal usage is
prohibited. It goes into the same direction as what OO does (see above)
only that it is not as strict.
Similarly you can create a structure of procedures that describe how you
are going to address the task of the program, without at that point
considering data in any detail.

How exactly do you do that? I mean, you can write down names of
procedures and which calls which but you need specific types once you
implement them - and likely earlier (i.e. when you do the design).
Eventually the procedures map onto the data structure but tend to share
'objects' with other procedures. I guess often you could group data and
procedures into 'classes' as they will have patterns of 'closed' usage,
but you don't have to.

On a separate tack, procedural doesn't hide methods (because it doesn't
have the language feature to do so) so a procedural program will trust
other programmers not to abuse code.

That's not true on this level of abstraction of the discussion. And
there are indeed procedural languages that allow access control: Modula
2 and PL/SQL come to mind. These have a concept of module which allows
to make certain things (procedures and data) only visible from inside
the module. I don't know Ada but I bet it has similar mechanisms.

Cheers

robert
 
M

Mike Stephens

Robert said:
What you call "partitioning" is the core of software engineering:
I do not believe that procedural
programs are automatically better or worse than object oriented ones.

Procedural gives you less to play with but prior to OO, you knew you had
to be very careful with partitioning your procedures and normalizing
your data. With OO people concentrate on objects and maybe give less
thought to structure amongst objects.

Perhaps OO is more like street gangs - robust, resilient, vicious and
highly self-contained, whereas procedural is more like the Roman or
British empires - managing enormous complexity by dividing things into
layers of delegation and control.
 
J

John Mair

The Ruby 'require' functionality is much closer to the C paradigm of
'include' than Ruby module inclusion.
 
M

Mike Stephens

John said:
The Ruby 'require' functionality is much closer to the C paradigm of
'include' than Ruby module inclusion.

An interesting feature of Ruby is that a module can contain a nested
module (as indeed with classes, although we are not using classes if we
do procedural). This suggests you could represent hierarchies of
functions ( a key element of structured programming) in hierarchies of
modules.
 
R

Robert Klemme

An interesting feature of Ruby is that a module can contain a nested
module (as indeed with classes, although we are not using classes if we
do procedural). This suggests you could represent hierarchies of
functions ( a key element of structured programming) in hierarchies of
modules.

I think there are two structuring mechanisms that should probably be
used for different things:

1. caller callee relationships, i.e. one function / procedure calls
other functions / procedures.

2. parallel and nested namespaces

Mechanism 1 is used to break down complex tasks in simpler tasks.
Mechanism 2 is orthogonal to that and should be used to group
functions / procedures which belong in the same domain (whatever that
is in a specific case, it can be a library, an algorithm etc.).
Nesting additionally allows to group different groups together to make
it clear which groups belong together (e.g. for a large library
different functionality which is only used by the library internally
could go into nested namespaces, although publicly visible these are
probably only used from within the lib). Another reason to use
nesting might be to group according to organizational hierarchies (as
is usually done with Java packages which often start with
"com.company").

Your statement sounds a bit like you wanted to use module nesting to
also model caller callee relationships. IMHO that would be a waste
because the caller callee relationship is already modeled in code via
actual calls.

Cheers

robert
 
D

Dave Howell

Often you see that Ruby can be object-oriented, functional or
procedural.
=20
What would you expect to see in a program that made you say "Ah this = is
procedural Ruby!"?

Fewer classes, and heavy use of variables.

mydata =3D File.open('myfile.txt').readlines

funparts =3D Array.new

loop mydata.size do |idx|
funparts << =
mydata[idx][/regex-that-matches-fun-parts/,1]
end

for funpart in funparts
puts funpart
end


This code assumes that the data is 'dead.' It's just sitting there, =
waiting for me to act upon it.=20

I've really had to pay attention to my coding. I keep reminding myself =
that Ruby will flow much better if I don't think of data as something I =
have to manipulate myself, but rather as entities whom are expecting me =
to tell them to manipulate themselves. "Don't make me search through you =
looking for the fun parts! You should do that work yourself, and just =
tell me what you come up with!"

puts (funparts =3D File.open('myfile.txt').readlines.collect do =
|line|
line[/regex-that-matches-fun-parts/,1]
end.compact).join("\n")

Instead of walking myself through the file contents line by line, =
picking out the good bits, I told the array to do it's own flippin' =
walking.=20


At least that's what I think procedure-oriented Ruby would look like.=20=
 
M

Mike Stephens

Robert said:
Your statement sounds a bit like you wanted to use module nesting to
also model caller callee relationships. IMHO that would be a waste
because the caller callee relationship is already modeled in code via
actual calls.

That's what I was floating.

In this thread we're mulling over what procedural Ruby means and
therefore whether Ruby does it easily, and whether the end result is a
viable style.

Procedural languages varied but typically your procedures would all be
at the top level so their relationships are only revealed by the code,
as you say. The objection to this is the absence of encapsulation and
therefore the prospect of people poking into your 'black boxes'. That
argument hinges around how much you can trust your fellow programmer.

I recently had a technical lead who was very good at programming
including eg .NET. One day I asked him which language he liked the most.
He replied surprisingly that he had recently become impressed with PHP.
I got the impression he was implying it took all day to do things in C#
whereas it takes no time in PHP. From what I've seen of PHP it is
essentially procedural.

Perhaps when you have lots of simple short programs, a procedural design
is just fine.
 
M

Mike Stephens

Dave said:
I keep reminding myself
that Ruby will flow much better if I don't think of data as something I
have to manipulate myself, but rather as entities whom are expecting me
to tell them to manipulate themselves.

The only thing is your data never manipulates itself. You always have to
write its methods. Getting an object to own its methods is no different
to getting a method to own its data.

Object style: data.method

Procedural Style: method (data)
 
R

Robert Klemme

That's what I was floating.

In this thread we're mulling over what procedural Ruby means and
therefore whether Ruby does it easily, and whether the end result is a
viable style.

Procedural languages varied but typically your procedures would all be
at the top level so their relationships are only revealed by the code,
as you say. The objection to this is the absence of encapsulation and
therefore the prospect of people poking into your 'black boxes'. That
argument hinges around how much you can trust your fellow programmer.

I recently had a technical lead who was very good at programming
including eg .NET. One day I asked him which language he liked the most.
He replied surprisingly that he had recently become impressed with PHP.
I got the impression he was implying it took all day to do things in C#
whereas it takes no time in PHP. From what I've seen of PHP it is
essentially procedural.

Does he know Ruby? If so, why did PHP impress him more? That would
be interesting to learn.
Perhaps when you have lots of simple short programs, a procedural design
is just fine.

For small programs (probably one off) it is usually not so important
what style you pick. I often find myself creating at least a few
classes even for those. I find that convenient (especially in Ruby
where the overhead is really small, often I can get away with a Struct
one liner). YMMV though.

Kind regards

robert


--=20
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
 

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
474,145
Messages
2,570,824
Members
47,370
Latest member
desertedtyro29

Latest Threads

Top