Reasons for object instantiation

Hi. Newbie here, with an even “stoopider” question than Ken’s.

I’ve been readings David A. Black’s fine “Well Grounded Rubyist” book.
Just reading now the chapter on classes. What I’m finding missing so far
are examples of why one would normally need more than one instance of a
(user created) class. Perhaps this comes from my procedural programming
(BASIC, back in 1970s high school). But I can’t see yet the general
kinds of things you can do with multiple class instances that you can’t
do programmatically, say, with a database. You send a ruby query to it,
read the response in to an object, and then work with it. OK so maybe
there’s more than one hit in the querie. Do you need to read each into
an array of objects in order to work with it?

A more specific example: Mr. Black’s example in the Classes chapter uses
the “ticket” class for a theater, and each ticket is endowed with
instance variables for price, availability, etc. But, is the idea to
write a (ticket sales) program that instantiates every instance of
ticket in one go (one per chair per show), just to scan them to see
where available=true? Couldn’t a DB search do the same thing?

Many thanks in advance!

-Kurt

As most of the time when object-orientation creates difficulties, they
are founded in the way you understand your current task as a stimulus to
write “code”. It isn’t. :wink:

When you make a database-query, you do not do that to justify your
programming work, but to provide the solution to a specific demand.

Like, for example…: “get me the job numbers of today’s unfinished
orders".

Nobody demands you to write a program. What they want, is

  • a list
  • numbers
    and that the list of numbers corresponds to real-world OBJECTS, they
    call “orders”. They do not want these objects.
    Admittedly, a way to provide the list may be code and a database-query.

Object-orientation has, originally, only one simple purpose: to allow a
software-developer to handle numbers and words as if they were
“real-world objects”, let’s say…, apples. That’s about all.

The advantage is in the simplicity of the program design. You hide all
the nifty algorithms until you need them. But before, you can play
around with your “objects” and imagine their behaviour under all
conceivable circumstances and even under “virtually impossible”
circumstances. That is, when object-oriented programming dynamites your
perception of the physical world by providing means to surpass it…, in
a way, which is not communicable with the vocabulary of procedural
languages. They are too “logic” and thus too limited.

I hope that we can read some more responses and, why not, opinions in
this thread.

Good night,

Michael

Kurt Euler wrote in post #1156967:

Hi. Newbie here, with an even “stoopider” question than Ken’s.

I’ve been readings David A. Black’s fine “Well Grounded Rubyist” book.
Just reading now the chapter on classes. What I’m finding missing so far
are examples of why one would normally need more than one instance of a
(user created) class. Perhaps this comes from my procedural programming
(BASIC, back in 1970s high school). But I can’t see yet the general
kinds of things you can do with multiple class instances that you can’t
do programmatically, say, with a database. You send a ruby query to it,
read the response in to an object, and then work with it. OK so maybe
there’s more than one hit in the querie. Do you need to read each into
an array of objects in order to work with it?

It can make things simpler. You could think of a record as an object,
and deal with the objects this way:

person1 = [1, “John”, 50]
person2 = [2, “Sally”, 50]

id = person1[0]
name = person1[1]
hours_worked = person1[2]
pay = 15 * hours_worked

puts “#{name}, whose id is #{id}, worked #{hours_worked} hours, earning
$#{pay}.”

–output:–
John, whose id is 1, worked 50 hours, earning $750.

But that code is somewhat cryptic. Ruby does have facilities for
turning db records into hashes, enabling you to do this:

person1 = {
id: 1,
name: “John”,
hours: 50,
}

person2 = {
id: 2,
name: “Sally”,
hours: 50,
}

pay = 15 * person1[:hours]

puts “#{person1[:name]}, whose id is #{person1[:id]}, worked
#{person1[:hours]} hours, earning $#{pay}.”

–output:–
John, whose id is 1, worked 50 hours, earning $750.

On the other hand, an instance of a class is a bundle
containing both data and methods, enabling you to do things
like this:

class Person
attr_accessor :id, :name, :hours

def initialize(id, name, hours)
self.id = id #calls accessor rather than directly setting @id
self.name = name
self.hours = hours
end

def pay(rate)
rate * self.hours
end
end

person1 = Person.new(1, “John”, 50)
person2 = Person.new(2, “Sally”, 50)

puts “#{person1.name}, whose id is #{person1.id}, worked
#{person1.hours} hours, earning $#{person1.pay(15)}.”

–output:–
John, whose id is 1, worked 50 hours, earning $750.

And as the methods get more numerous and complex, it can
be more convenient to have the methods bundled with the
object, for instance when calling a method that takes
a Person as an argument.

Also note, the accessor methods can be used to validate the entered
data:

class Person
attr_accessor :id, :hours
attr_reader :name

def initialize(id, name, hours)
self.id = id #calls accessor rather than directly setting @id
self.name = name
self.hours = hours
end

def pay(rate)
pay = rate * self.hours
pay_str = sprintf("%.2f", pay)
currency = “$”
“#{currency}#{pay_str}”
end

def name=(str)
@name = str.capitalize
end
end

person1 = Person.new(1, “john”, 50)
person2 = Person.new(2, “Sally”, 50)

puts “#{person1.name}, whose id is #{person1.id}, worked
#{person1.hours} hours, earning #{person1.pay(15)}.”

–output:–
John, whose id is 1, worked 50 hours, earning $750.00.

However, maybe a better answer is: you don’t get to know
“why classes” yet. Think of classes as a trick you are
learning. You don’t necessarily have to know why the trick
is useful, but if you learn the trick, then someday you
may find some use for it. When programming, it’s always
better to have alternatives.

Also consider the fact, that ruby hashes and arrays are instances of a
class. Think about how you would implement them without using classes.
Is it as convenient?

In any case, you can write lots of useful programs with ruby
without defining your own classes–so don’t worry too much
about it.

Kurt Euler wrote in post #1156967:

What I’m finding missing so far
are examples of why one would normally need more than one instance of a
(user created) class…I can’t see yet the general
kinds of things you can do with multiple class instances that you can’t
do programmatically, say, with a database.

There are usually many ways one can write a computer program. Some are
more efficient than others. Some are more reliable than others. Some
are more maintainable than others. Some are more convenient than
others. Some have code that is easier to understand than others.

I can do subtraction by adding negative numbers, so I don’t understand
why ruby has the binary minus operator?

I can store data in parallel arrays, so I don’t understand what the
point of Hashes are?

I can create any Integer with the binary plus operator and 1, so I don’t
understand why ruby allows you to use other Integer literals, like 8?

I can do anything in Python that I can do in Ruby, so what is the point
of Ruby?

Getting the idea? Alternatives are a good thing.

THx all. Comments help. I’ll continue to plow ahead in the Rubyist,
where things will no doubt come together.

In Ruby, the world makes sense from Ruby.

Ruby gives you certain data structures - hash and arrays are the most
important ones; of course also @ivars for storing stuff in your objects.

You need to model the world according to how ruby sees it - that is, in
objects.

Then you apply operations on your objects to achieve the desired result.

The example of a database is the same as thinking of dormant objects in
your database and waking them up every now and then - it is as if you
would have serialized the objects via yaml or marshall and then
restoring their initial state.

Then you modify it, and store the new state.

But not always do you have a full database. What about plain old
textfiles?

You need code to make sense of plain textfiles and ruby helps immensely
here.

File.readlines()
File.read()

Couldn’t a DB search do the same thing?

You could modify the DB without ruby, yes.

But why would you want to memorize all SQL commands when you can
abstract them away with operations on objects instead, where you simply
don’t have to worry about building the SQL string yourself?