Object-orientedIt is a very confusing wording. To say that everything is object-oriented will make others think you are fashionable. Ruby claims to be an object-oriented scripting language; but what exactly is "object-oriented"?
We already have all kinds of answers, but all of them probably come down to the same thing. Instead of summing it up quickly, let's take a moment to think about the traditional programming pattern first.
Traditionally, a programming problem starts with various data that arises and processes the data. In this mode, data is rigid, passive and useless; it completely relies on the bulky, active, logical, and omnipotent process body.
The problem with this approach is that the program is written by programmers, and they can only record a few details in their work. And as the project grows, its core grows to the point where it is difficult to remember how the entire project works. Subtle mistakes and knocking errors become increasingly easy to cause bugs that are difficult to detect. Complex and unexpected interference begins to appear in the core, and maintenance becomes like trying to catch an angry squid and not let its tentacles touch your face. Of course, for traditional methods, we also have many ways to guide you to narrow down and detect these bugs, but a better solution is to completely change the way we work.
What object-oriented does is to let us hand over realistic, repetitive logical work to the data itself; it changes our concept of data from passive to active. In other words:
The inside of the "machine" mentioned above may be quite simple or complicated; we cannot peek from the outside, nor can we allow ourselves to open the machine shell (unless we do find something wrong), so we only need to operate the data by turning the switch and reading the scale. Once the machine is built, we no longer have to consider how it works.
Perhaps, you will feel that this is increasing your workload for no reason, but this method can effectively prevent things from moving in a bad direction.
Let's start with a simple example of no practical value but at least some of the concepts. Your car has a taximeter. Its job is to record the driving path since the last reset.
Program. How will we model in programming language? In C, this meter may be a numeric variable, probably of float type. This program will increase its value every certain stroke and reset to zero when appropriate. Where will something go? A bed bug in the program will assign a pseudo value to this variable for no reason, which can happen for some unexpected reasons. Anyone with experience in C programming will know that it will take hours or days to get rid of this bed bug that is ridiculously simple when it is found. (The moment you find it, you will often pat your forehead hard)
The same problem starts from a completely different perspective when using object-oriented. When designing it, the first thing programmers will ask is not "What is the most similar data type?" but "What exactly does this thing do?" This difference leads to something slightly more difficult. We need to take some time to determine what the taximeter is for and how the outside world wants to manipulate it. Then we decide to build a small machine that allows us to increase, reset, read values, and nothing else.
We do not provide a method for assigning arbitrary values to the meter: Why? Because we all know that the meter doesn't work that way. You can only do the defined things to the meter, and those things that allow us to do. Therefore, if something else in the program wrongly assigns a value to it (such as the temperature controller of the car), this immediately means an error occurs. When running it (or when compiled, depending on the nature of the language), we will be told to prohibit assigning arbitrary values to the meter object. The message given may not be so clear, but it should be close to its true cause. This does not prevent the error from happening, right? But it quickly pointed out the problem directly to us. This is just one of many ways that OO programming will save us a lot of time.
Generally, we will consider abstracting the above thing, because building a factory to build machines is much simpler than building them separately. We do not want to directly build a separate meter;
In other words, we want all the meters to be made from a model. This pattern (called the meter factory if you like) corresponds to what we call a class, and each individual meter generated by it (or made from a factory) corresponds to an object. Many object-oriented languages require us to define its class before we have a new object, but that is not the case with Ruby.
Of course, using object-facing language does not mean that there will be good object-facing design. In fact, any language can write vague, careless, wormy, low-achieving and unstable code. What Ruby can do for you (as a counterexample, especially C++) is to make OO programming practice natural enough, even if you only use it on a small scale, you won’t feel that you have to rely on ugly code to improve efficiency. We will discuss the mechanisms for Ruby to achieve these predetermined goals in depth with this manual; the next chapter will be "Switches and Scale Tables" (Object Methods), and then we will discuss "factories" (class). Will you still come with us?
We already have all kinds of answers, but all of them probably come down to the same thing. Instead of summing it up quickly, let's take a moment to think about the traditional programming pattern first.
Traditionally, a programming problem starts with various data that arises and processes the data. In this mode, data is rigid, passive and useless; it completely relies on the bulky, active, logical, and omnipotent process body.
The problem with this approach is that the program is written by programmers, and they can only record a few details in their work. And as the project grows, its core grows to the point where it is difficult to remember how the entire project works. Subtle mistakes and knocking errors become increasingly easy to cause bugs that are difficult to detect. Complex and unexpected interference begins to appear in the core, and maintenance becomes like trying to catch an angry squid and not let its tentacles touch your face. Of course, for traditional methods, we also have many ways to guide you to narrow down and detect these bugs, but a better solution is to completely change the way we work.
What object-oriented does is to let us hand over realistic, repetitive logical work to the data itself; it changes our concept of data from passive to active. In other words:
- We no longer let data make us reach in and take out things like an open box.
- We think of it as a sealed machine with switches and dials.
The inside of the "machine" mentioned above may be quite simple or complicated; we cannot peek from the outside, nor can we allow ourselves to open the machine shell (unless we do find something wrong), so we only need to operate the data by turning the switch and reading the scale. Once the machine is built, we no longer have to consider how it works.
Perhaps, you will feel that this is increasing your workload for no reason, but this method can effectively prevent things from moving in a bad direction.
Let's start with a simple example of no practical value but at least some of the concepts. Your car has a taximeter. Its job is to record the driving path since the last reset.
Program. How will we model in programming language? In C, this meter may be a numeric variable, probably of float type. This program will increase its value every certain stroke and reset to zero when appropriate. Where will something go? A bed bug in the program will assign a pseudo value to this variable for no reason, which can happen for some unexpected reasons. Anyone with experience in C programming will know that it will take hours or days to get rid of this bed bug that is ridiculously simple when it is found. (The moment you find it, you will often pat your forehead hard)
The same problem starts from a completely different perspective when using object-oriented. When designing it, the first thing programmers will ask is not "What is the most similar data type?" but "What exactly does this thing do?" This difference leads to something slightly more difficult. We need to take some time to determine what the taximeter is for and how the outside world wants to manipulate it. Then we decide to build a small machine that allows us to increase, reset, read values, and nothing else.
We do not provide a method for assigning arbitrary values to the meter: Why? Because we all know that the meter doesn't work that way. You can only do the defined things to the meter, and those things that allow us to do. Therefore, if something else in the program wrongly assigns a value to it (such as the temperature controller of the car), this immediately means an error occurs. When running it (or when compiled, depending on the nature of the language), we will be told to prohibit assigning arbitrary values to the meter object. The message given may not be so clear, but it should be close to its true cause. This does not prevent the error from happening, right? But it quickly pointed out the problem directly to us. This is just one of many ways that OO programming will save us a lot of time.
Generally, we will consider abstracting the above thing, because building a factory to build machines is much simpler than building them separately. We do not want to directly build a separate meter;
In other words, we want all the meters to be made from a model. This pattern (called the meter factory if you like) corresponds to what we call a class, and each individual meter generated by it (or made from a factory) corresponds to an object. Many object-oriented languages require us to define its class before we have a new object, but that is not the case with Ruby.
Of course, using object-facing language does not mean that there will be good object-facing design. In fact, any language can write vague, careless, wormy, low-achieving and unstable code. What Ruby can do for you (as a counterexample, especially C++) is to make OO programming practice natural enough, even if you only use it on a small scale, you won’t feel that you have to rely on ugly code to improve efficiency. We will discuss the mechanisms for Ruby to achieve these predetermined goals in depth with this manual; the next chapter will be "Switches and Scale Tables" (Object Methods), and then we will discuss "factories" (class). Will you still come with us?