6

I'm new to Ruby. I'm learning abstraction principle in ruby.As I understood Procedural abstraction is hiding the implementation details from the user or simply concentrating on the essentials and ignoring the details.

My concern is how to implement it

1) Is it a simple function calling just like this

# function to sort array
# @params array[Array] to be sort

def my_sort(array)
  return array if array.size <= 1

  swapped = false
  while !swapped
    swapped = false
    0.upto(array.size-2) do |i|
      if array[i] > array[i+1]
        array[i], array[i+1] = array[i+1], array[i]
        swapped = true
      end
    end
  end

  array
end

and calling like this

sorted_array = my_sort([12,34,123,43,90,1])

2) How does Data Abstraction differs from Encapsulation

As I understood Data Abstraction is just hiding some member data from other classes.

spickermann
  • 100,941
  • 9
  • 101
  • 131
Bibek Sharma
  • 3,210
  • 6
  • 42
  • 64

3 Answers3

5

Data abstraction is fundamental to most object oriented language - wherein the classes are designed to encapsulate data and provide methods to control how that data is modified (if at all), or helper methods to derive meaning of that data.

Ruby's Array class is an example of Data Abstraction. It provides a mechanism to manage an array of Objects, and provides operations that can be performed on that array, without you having to care how internally it is organized.

arr = [1,3,4,5,2,10]
p arr.class # Prints Array
p arr.sort # Prints [1,2,3,4,5,10]

Procedural abstraction is about hiding implementation details of procedure from the user. In the above example, you don't really need to know what sorting algorithm sort method uses internally, you just use it assuming that nice folks in Ruby Core team picked a best one for you.

At the same time, Ruby may not know how to compare two items present in the Array always. For example, below code would not run as Ruby does not know how to compare strings and numbers.

[1,3,4,5,"a","c","b", 2,10].sort 
#=> `sort': comparison of Fixnum with String failed (ArgumentError)

It allows us to hook into implementation and help with comparison, even though underlying sorting algorithm remains same (as it is abstracted from the user)

[1,3,4,5,"a","c","b", 2,10].sort { |i,j| 
    if i.class == String and j.class == String
        i <=> j
    elsif i.class == Fixnum and j.class == Fixnum
        i <=> j
    else
        0
    end
}
#=> [1, 3, 4, 5, 2, 10, "a", "b", "c"]

When writing code for your own problems, procedural abstraction can be used to ensure a procedure often breaks down its problem into sub-problems, and solves each sub-problems using separate procedure. This allows, certain aspects to be extended later (as in above case, comparison could be extended - thanks to Ruby blocks, it was much easier). Template method pattern is good technique to achieve this.

Wand Maker
  • 18,476
  • 8
  • 53
  • 87
3

You are returning an array from the method. Data structures are implementation details. If you change the data structure used in the method, you will break the client code. So your example does not hide the implementation details. It does not encapsulate the design decisions so that the client's are insulated from the internal implementation details.

bparanj
  • 433
  • 2
  • 6
  • 15
3

Definition of 'Abstraction' : the quality of dealing with ideas rather than events.

Referring to this answer difference between abstraction and encapsulation? and my understanding I found that in your code the method my_sort fully justifies the Encapsulation as it encapsulates the behavior related to sorting of any single dimension array. However it lacks the abstraction as the method my_sort knows the type of data its gonna process on.

It would have justified Abstraction if it had not known / cared the type of data that comes in via params. In other words, it should have sorted any object that comes in no matter whether it is a list of Fixnum or String or other sortable datatypes.

Encapsulation:

We normally use access modifiers (public, private,..) to differentiate the data/behavior that are to be exposed to the clients and that are to be used internally. The public interface ( Exposed to clients ) are not subject to change as far as possible. However, the private are the behaviors that can change and should not in any case impact the expected behavior of the code that clients rely upon.
Also we separate the sensitive data/behavior to private/protected to prevent accidental modification / misuse. This makes client not to rely on the portion of the code that might change frequently.

  • So one always need to segregate the core logic to private scope.

Abstraction:

Example: In case of church there is an abstraction between the confessor and the father / priest. The confessor should not have any idea about the name or any detail of the priest and vice-versa. Anyone can confess and yet hide his/her identity no matter how big mistakes/crimes he/she had committed.

Community
  • 1
  • 1
Shiva
  • 11,485
  • 2
  • 67
  • 84