Bắt đầu từ con số không với Ruby?

360

“Ruby có ngoại hình đơn giản, nhưng có tâm hồn rất phức tạp giống như con người chúng ta vậy.” – Matz, cha đẻ của ngôn ngữ lập trình Ruby.

Vì sao bạn nên học Ruby?

Đối với tôi, Ruby là một ngôn ngữ đẹp. Bạn sẽ thấy việc viết code trong Ruby rất mượt mà và tự nhiên.

Mặt khác, một trong những nguyên nhân khiến cho Ruby nổi tiếng nằm ở Rails: một framework được dùng bởi Twitter, Basecamp, Airbnb, Github, và nhiều công ty khác.

Nguồn gốc

Ruby là một ngôn ngữ lập trình open source vô cùng mạnh mẽ với sự đơn giản mà hiệu quả. Với các cú pháp đầy thanh lịch giúp cho việc đọc và viết vô cùng dễ dàng.

Hãy bắt đầu với nền tảng của Ruby

Variables

Bạn có thể hiểu đơn giản rằng một variable là một từ chứa một giá trị. Đơn giản thế thôi.

Trong Ruby, rất dễ để ta define một variable và cho nó một giá trị. Giả sử bạn muốn cho giá trị là 1 vào một variable với tên gọi cũng là một.

Quá dễ đúng không?

Bạn có thể cho bất kì giá trì gì mình muốn cho variable mà bạn thích. Trong ví dụ trên, variable tên là two chứa giá trị 2 và variable tên là  some_number có giá trị 10,000.

Ngoài integers, ta còn có thể dùng booleans (true/false), strings, symbols, float, và các dạng data types khác.

Conditional Statements: Điều khiển Flow

Conditional statements sẽ có nhiệm vụ xem xét tính true/false của một statement. Nếu kết quả là True (Đúng), thì nội dung bên trong sẽ được xử lí.

Bởi vì 2 lớn hơn 1 nên dòng chữ “2 is greater than 1” sẽ được hiện ra.

Else statement sẽ được thực hiện khi ta gặp kết quả False(Sai):

Bởi 1 không lớn hơn 2, nên code trong Else statement sẽ được xử lí.

Ngoài ra thì bạn cũng có thể dùng tới elsif statement, vốn kết hợp cả 2 loại trên:

Tôi thì lại thích dùng if statement  sau khi code đã được thực hiện:

Nhìn rất đẹp mà lại ngắn gọn. Đó là thế mạnh của Ruby.

Looping/Iterator

Trong Ruby, chúng ta có thể iterate bằng nhiều hình thức khác nhau: while, for và each.

Vòng lặp While: Miễn là kết quả của statement vẫn là true, nội dung code nằm trong statement sẽ luôn được thực hiện. Như vậy, Code sẽ in và hiển thị từ số 1 tới 10 trong ví dụ dưới đây:

Vòng lặp For: Với Statement được cho ra, nội dung code sẽ được thực hiện cho đến khi thõa mãn yêu cầu của statement đó.

Each iterator: Với bất kì array của giá trị, nó sẽ iterate  từng giá trị một.

Điểm khác biết giữa For và Each là Each thực hiện chính xác từng giá trị được cho trong khi For sẽ xuất hiện những giá trị không mong muốn nằm ngoài yêu cầu.

Array: Collection/List/Data Structure

Giả sử như bạn muốn lưu integer 1  vào một variable. Nhưng giờ thì bạn muốn lưu 2, và rùi 3,4,5….

Vậy có cách nào để có thể lưu những integers mà bạn muốn mà không phải cứ làm cách thủ công như vậy. Ruby sẽ cung cấp giải pháp cho bạn.

Array là một collection dùng để lưu trữ một list các values.

Rất là đơn giản, chúng ta tạo ra một array và lưu nó vào my_integer.

Bạn sẽ tự hỏi rằng “làm cách nào để lấy giá trị từ array đó?”. Trong Arrays có một khái niệm gọi là Index. Bắt đầu với index 0 và cứ thể tăng dần lên.

Sử dụng cú pháp Ruby, nó rất đơn giản để hiểu:

Giờ nếu bạn muốn lưu strings thay vì integers, đại loại như list tên họ hàng của bạn chẳng hạn:

Không có gì khác ngoài trừ giờ ta dùng chữ thay cho số.

Giờ khi nói về array data structure, ta ám chỉ việc đụng tới các giá trị trong array đó.

Phương pháp thường thấy dùng để thêm giá trị vào array là push và <<.

Push cực kì đơn giản, như ví dụ sau đây:

Phương pháp << thì có chút khác biệt với:

Bạn có thể thấy sự khác biệt nằm ở dấu chấm. Có thể nói:

Cũng chính là

Ruby thật là tuyệt đúng không?

Giờ hãy nói thêm về một loại Data Structure khác.

Hash: Key-Value Data Structure/Dictionary Collection

Chúng ta đều đã biết arrays thực chất chính là array với số. Thế nhưng nếu chúng ta dùng số thứ tự thì sao? Một số data structures có thể dùng số, string, hoặc các dạng type khác. Hash data structure là một trong số đó.

Hash là một collection các cặp key-value:

Trong đó, Key sẽ ám chỉ index của value. Vậy để truy cấp vào value của Hash thì ta sẽ thông qua Key.

Sau đây là một hash về tôi với Key là họ tên, nickname, sắc tộc:

Trong ví dụ trên, tôi cho in ra mọi thông tin về mình.

Một điều khá tuyệt của hash là chúng ta có thể dùng bất cứ thứ gì làm value. Tôi sẽ thêm key “age” và số tuổi của mình là 24 vào value.

Giờ chúng ta sẽ thêm các nhân tố khác vào một hash. Key dẫn tới value chính là đặc điểm làm nên Hash nên việc thêm vào cũng sẽ theo qui luật như vậy.

Bạn có thấy việc thêm một giá trị vào hash rất đơn giản đúng không?

Iteration: Vòng lặp thông qua Data Structures

Array iteration thật sự rất đơn giản. Ruby developer thường dùng each iterator:

Each iterator ở trên hoạt động bằng cách đi qua từng yếu tố trong array như là một thông số. Trong ví dụ trên, chúng ta sẽ in ra từng yếu tố đó.

Với hash data structure, ta cũng có thể dùng each iterator để đi qua 2 thông số trong cùng một block: key và value.

Ta sẽ đặt tên cho hai tham số này là key và value cho khỏi bị nhầm lẫn.

Classes & Objects

Là một ngôn ngữ lập trình object oriented, Ruby dùng class và object.

“Class” là một cách để define objects. Ví dụ như xe ô tô có nhiều loại.

“Objects” có 2 đặc điểm: data và behavior. Ví dụ như ô tô có data về số bánh xe, chiều dài cũng như behavior với khả năng tăng tốc và phanh.

Trong lập trình object oriented, ta gọi data là “attributes”  và behavior là “methods.”

Ruby Object Oriented Programming Mode: On

Sau đây là một cú pháp trong Ruby cho Class:

Ta define Vehicle với class statement và kết thúc bằng end.

Objects chính là đại diện cho class. Ta tạo ra instance bằng phương pháp .new

Tại đây, vehicle là object (hay instance)  của class: Vehicle

vehicle class có 4 attributes: bánh xe, loại thùng tank, số ghế và vận tốc.

Chúng ta đã sử dụng phương pháp initialize (khởi tạo). Với tên gọi khác là constructor bởi khi bạn tạo ra vehicle object, đồng thời ta cũng sẽ define các attributes của nó luôn.

Giả sử bạn rất thích chiếc Tesla Model S và muốn tạo một object như vậy. Bao gồm 4 bánh, là xe điện, 5 chỗ và chạy được với vận tốc tối đa là 250km/hour (155 mph).

4 wheels + electric tank + 5 seats + 250km/hour maximum speed = tesla_model_s.

Vậy là ta đã set up lên Tesla’s attributes. Nhưng truy cập vào bằng cách nào?

Tất nhiên là bằng cách gửi tin tới object để hỏi về chúng.

Trong ví dụ trên, ta dùng hai cách number_of_wheels và set_number_of_wheels. Hay còn được biết tới là getter and setter. Đầu tiên là ta lấy một giá trị với get, thứ hai ta có thể đặt ra một giá trị với set.

Trong Ruby, ta có thể dùng những phương pháp trên với attr_reader, attr_writer và attr_accessor.

  • attr_reader: áp dụng phương pháp getter

  • attr_writer: áp dụng phương pháp setter

  • attr_accessor: áp dụng cả 2 phương pháp trên

Ngoài ra ta còn có những phương pháp khác như “make_noise” method

Khi ta call thì nó sẽ return với một string là “VRRRRUUUUM”.

Encapsulation: Cất giấu thông tin

Encapsulation là cách giới hạn việc truy cập trực tiếp vào objects’ data đồng thời tạo điều kiện cho hoạt động cho data.

Nói cách khác những thông tin bên trong sẽ được giấu kín.

Như vậy, trong Ruby, ta sẽ dùng một phương pháp để truy cập dữ liệu trực tiếp:

Như vậy, ta đã áp dụng Person class.

Vậy thì để truy cập được nhưng thông tin này thì phải làm sao? call name và age method?

Rõ ràng là không được. Đó là bởi chúng ta phải dùng phương thức truy cập trực tiếp như sau:

Inheritance: behaviors và characteristics

Một số các objects  đều có những điểm chung với nhau: Behavior và characteristics.

Hãy thử tưởng tượng một chiếc xe với những attributes như số bánh xe, vận tốc tối đa, etc…

Car class đã được implement 🙂

Trong Ruby, chúng ta dùng < operator để chỉ định rằng một class được thừa kế từ class khác. Một ElectricCar class sẽ thừa kế từ Car class.

Đơn giản vậy đấy, ta không cần dùng thêm phương pháp nào bởi class này đã có sẵn thông tin được thừa kế từ Car.

Module: Một Toolbox

Chúng ta có thể xem module như một toolbox chứa đựng một set các constants và phương pháp.

Một ví dụ của Ruby module là Math.

Và phương pháp .sqrt:

Chúng ta cũng có thể áp dụng module của mình và dùng nó trong class. Ta có một RunnerAthlete class:

Và áp dụng module Skill vào để có average_speed

Vậy làm sao để thêm module vào cho classes để nó có được tính cách trên (average_speed)? Bạn cứ đơn giản là ghi thẳng vào luôn!

Bạn có thể thấy phần “include Skill”! Giờ thì bạn đã có thể xài phương pháp này trong instance của RunnerAthlete class.

Tuy vậy bạn cần phải nhớ những điều sau:

  • module có thể không có instances
  • module có thể không có subclass
  • module được define bằng module

Nguồn: blog.topdev.vn via medium

 

SHARE