12/08/2018, 15:18

Hash Parameter - Sử dụng hash làm parameter cho method trong Ruby

Trong Ruby, khi phải khai báo và sử dụng một method có số lượng parameter lớn, lập trình viên thường gặp khó khăn trong việc nhớ đủ các parameter cũng như thứ tự của chúng trong method. Hôm nay mình xin giới thiệu một giải pháp cho vấn đề này. Hash là một tập hợp các cặp giá trị (key - value), ...

Trong Ruby, khi phải khai báo và sử dụng một method có số lượng parameter lớn, lập trình viên thường gặp khó khăn trong việc nhớ đủ các parameter cũng như thứ tự của chúng trong method. Hôm nay mình xin giới thiệu một giải pháp cho vấn đề này.

Hash là một tập hợp các cặp giá trị (key - value), giá trị của value được truy vấn thông qua key. Các thao tác cơ bản trên hash bao gồm khai báo, truy vấn, gán giá trị và tạo mới một cặp giá trị (key - value).

elements = {"H" => "Hydrogen", "Li" => "Lithium"}
=> {"H" => "Hydrogen", "Li" => "Lithium"}
elements["H"]
=> "Hydrogen"
elements["H"] = "Hyrdo"
=> "Hydro"
elements["Ne"] = "Neon"
=> "Neon"

Giả sử chúng ta khai báo class People như sau.

class People
  attr_accessor :name, :age, :gender, :job

  def initialize name, age, gender, job
    self.name = name
    self.age = age
    self.gender = gender
    self.job = job
  end

  def show
    puts "Name: #{name}"
    puts "Age: #{age}"
    puts "Gender: #{gender}"
    puts "Job: #{job}"
  end
end

Chúng ta khởi tạo một đối tượng, truyền các parameter theo đúng thứ tự và gọi method show trên đối tượng đó.

people = People.new "Tom and Jerry", 10, "Male", "Actor"
people.show

Kết quả trả về.

Name: Tom and Jerry
Age: 10
Gender: Male
Job: Actor

Mọi chuyện vẫn ổn cho đến khi chúng ta quên thứ tự truyền vào của các parameter và gọi method show trên đối tượng đó.

people = People.new "Tom and Jerry", 10, "Actor", "Male"
people.show

Kết quả trả vế không còn đúng như ta mong muốn.

Name: Tom and Jerry
Age: 10
Gender: Actor
Job: Male

Vậy chúng ta phải làm thế nào để phòng tránh trường hợp trên xảy ra?

Sử dụng hash như là parameter của method, ta viết lại class People như sau.

class People
  attr_accessor :name, :age, :gender, :job

  def initialize params
    self.name = params[:name]
    self.age = params[:age]
    self.gender = params[:gender]
    self.job = params[:job]
  end

  def show
    puts "Name: #{name}" h
    puts "Age: #{age}"
    puts "Gender: #{gender}"
    puts "Job: #{job}"
  end
end

Khởi tạo đối tượng, sử dụng hash làm parameter truyền vào và gọi method show trên đối tượng đó.

people = People.new {:name => "Tom and Jerry", :age => 10, :gender => "Male", :job => "Actor"}
people.show

Kết quả nhận được.

Name: Tom and Jerry
Age: 10
Gender: Actor
Job: Male

Chúng ta có thế bó cặp dấu "{}" nếu hash là parameter duy nhất hoặc cuối cùng của method.

people = People.new :name => "Tom and Jerry", :age => 10, :gender => "Male", :job => "Actor"
people.show

Nếu chúng ta sử dụng :symbol làm key cho hash, chúng ta có thể bỏ dấu ":" của symbol và thay thế dấu "=>" bằng ":"

people = People.new name: "Tom and Jerry", age: 10, gender: "Male", job: "Actor"
people.show

Chuyện gì xảy ra khi lỗi typo xảy ra, chúng ta vô tính gõ sai key của hash (job thành jod).

people = People.new name: "Tom and Jerry", age: 10, gender: "Male", jod: "Actor"
people.show

Code vẫn chạy và không raise error, attribute job của people nhận giá trị nil (default value của hash). Vậy chúng ta phải làm thế nào để phòng tránh trường hợp trên xảy ra?

Để phòng tránh lỗi typo bị bỏ qua khi sử dụng hash làm parameter cho method, ta có thể sử khai báo hash với các căp key - value được gán giá trị mặc định. Ta viết lại class People như sau:

class People
  attr_accessor :name, :age, :gender, :job

  def initialize name: nil, age: nil, gender: nil, job: nil
    self.name = name
    self.age = age
    self.gender = gender
    self.job = job
  end

  def show
    puts "Name: #{name}"
    puts "Age: #{age}"
    puts "Gender: #{gender}"
    puts "Job: #{job}"
  end
end

Khởi tạo đối tượng, sử dụng hash làm parameter truyền vào và gọi method show trên đối tượng đó.

people = People.new name: "Tom and Jerry", age: 10, gender: "Male", jod: "Actor"
people.show

Khi gặp lỗi typo như đoạn chương trình trên, ruby lập tức raise error và dừng chương trình

unknown keyword: jod (ArgumentError)
0