# ตัวแปร

ตัวแปร (ภาษาอังกฤษ: Variable) นั้นเป็นสิ่งที่สำคัญมากในการเขียนโปรแกรม ถ้ายังจำตอนเรียนคณิตศาสตร์ชั้นมัธยมได้ เราจะรู้จักกับตัวแปรในรูปแบบ `x`, `y`, `z` และสมการเชิงเส้นต่างๆ (นึกถึงความหลัง 😂)

แต่ในเชิงของการเขียนโปรแกรม และในภาษา Ruby ตัวแปรคือสิ่งที่เก็บข้อมูลอะไรก็ได้ เพื่อนำไปใช้ประโยชน์ต่อไป ถ้าในทางคณิตศาสตร์ตัวแปรจะเอาไว้แทนตัวเลขอย่างเดียว

ถ้าจะอธิบายเป็นภาษาชาวบ้าน ตัวแปรก็เป็นแค่กล่องเก็บของนั่นเอง 📦

## การสร้างตัวแปร

การสร้างตัวแปร (บ้างอาจเรียก การ "ประกาศ" ตัวแปร) ทำได้โดยการตั้งชื่อของตัวแปร ตามด้วยเครื่องหมายเท่ากับ `=` แล้วตามด้วยค่าของข้อมูลทางด้านขวา

{% embed url="<https://repl.it/@narze/variables-declare?lite=true>" %}

จากตัวอย่างด้านบน เป็นการประกาศตัวแปร 3 ตัว ได้แก่ :

* ชื่อ `x` ให้มีค่าเท่ากับ 1
* ชื่อ `sum` มีค่าเป็น `1 + 2 + 3 + 4 + 5` ซึ่งก็คือ `15`
* ชื่อ `hello_world` มีค่าเป็นสตริง `"สวัสดี ชาวโลก"` 👽

{% hint style="info" %}
สำหรับผู้ที่เคยเขียนโปรแกรมภาษาอื่นๆ ที่การสร้างตัวแปรอาจจะต้องมีคีย์เวิร์ด `var` หรือ `let` และอาจต้องกำหนดประเภทของตัวแปร เช่น `int` หรือ `string`จะสังเกตได้ว่า ภาษา Ruby นั้นไม่ต้องมีทั้งคีย์เวิร์ดและประเภทของตัวแปรเลย ซึ่งมีข้อดีคือเขียนได้ง่ายและเร็ว
{% endhint %}

{% hint style="info" %}
การตั้งชื่อตัวแปรในภาษา Ruby นิยมตั้งชื่อแบบ `snake_case` นั่นคือเป็นตัวพิมพ์เล็กทั้งหมด และถ้ามีมากกว่า 1 คำ ให้คั่นด้วยขีดล่าง`_` (Underscore)
{% endhint %}

เมื่อเราประกาศตัวแปรเสร็จแล้ว ลองใช้คำสั่ง `puts` กับตัวแปรเหล่านี้ดู

{% embed url="<https://repl.it/@narze/variables-puts?lite=true>" %}

นอกจากนี้ เรายังนำตัวแปรมาใช้ซำ้ได้ เช่นการใช้ตัวแปรมาบวกเลขกัน หรือเรียก[เมธอด](/courses/ruby/methods.md#method)กับตัวแปรสตริง เป็นต้น

{% embed url="<https://repl.it/@narze/variables-methods?lite=true>" %}

จากตัวอย่างด้านบน เป็นการใช้งานตัวแปร ได้แก่ :

* `x + sum` โดยที่ `x` เป็น `1` และ  `sum`เป็น `15` จึงได้ค่าออกมาเป็น `16`
* `sum * 2` โดยที่ `sum` เป็น `15` จึงได้ค่าออกมาเป็น `30`
  * สังเกตได้ว่า ค่าของตัวแปรต่างๆ จะยังเป็นค่าเดิม ไม่เปลี่ยนแปลง
* `hello_world.reverse` คือการนำค่าสตริงในตัวแปร `hello_world` มากลับด้าน ทำให้ได้ค่าออกมาเป็น `กลโวาช ีดสัวส`
* `hello_world + x` บรรทัดนี้จะทำให้โปรแกรมเกิดข้อผิดพลาดหรือ Error ขึ้น เพราะว่าเป็นการบวกกันของสตริง และตัวเลขเข้าด้วยกัน

{% hint style="info" %}
**เราลองมาดู Error ที่เกิดขึ้น**

\`Traceback (most recent call last): \`

`` `1: from main.rb:8:in ``'\`

`main.rb:8:in`+': no implicit conversion of Integer into String (TypeError) exit status 1

**แปลว่า :**

จากโปรแกรม `main.rb` บรรทัดที่ 8 ในเมธอดการบวก `+`ไม่สามารถแปลงจำนวนเต็ม (ในที่นี้หมายถึงตัวแปร `x` ที่มีค่าเป็นเลขจำนวนเต็ม `1`) ให้เป็นสตริง เพื่อไปบวกกับตัวแปร `hello_world`ที่เป็นสตริงได้นั่นเอง
{% endhint %}

ซึ่งถ้าจะแก้ไขปัญหาของโค้ดส่วนนี้ จะต้องทำการแปลงค่า `x` ให้เป็นสตริงก่อน ด้วยเมธอดการแปลงค่าเป็นสตริง `.to_s` ซึ่งเมื่อเราแปลงแล้ว การบวกสตริงสองตัวเข้าด้วยกัน จะนับเป็นการเอาคำมาต่อท้ายนั่นเอง

{% embed url="<https://repl.it/@narze/variables-methods-fix?lite=true>" %}

{% hint style="info" %}
การแปลงประเภทข้อมูลในภาษา Ruby จะเป็นเมธอดที่นิยมตั้งชื่อเป็นรูปแบบของ `.to_*` เช่น

* แปลงเป็นสตริง (To String) ใช้ `.to_s`
* แปลงเป็นตัวเลขแบบจำนวนเต็ม (To Integer) ใช้ `.to_i`
* แปลงเป็นตัวเลขแบบทศนิยม (To Float) ใช้ `.to_f`
  {% endhint %}

## การเขียนค่าซำ้ในตัวแปร หรือประกาศตัวแปรใหม่

จากตัวอย่างก่อนหน้านี้ จะเห็นว่าเมื่อประกาศตัวแปรไปแล้ว ค่าจะเป็นเท่าเดิมเสมอแม้ว่าจะมีการใช้ซำ้ในหลายๆ บรรทัดก็ตาม

แต่ถ้าเราทำการประกาศตัวแปรโดยใช้ชื่อเดิม จะถือว่าเป็นการล้างค่าตัวแปรเดิมไปเลย ตามตัวอย่างโค้ดด้านล่างนี้

{% embed url="<https://repl.it/@narze/variables-methods-redeclare?lite=true>" %}

เมื่อถึงบรรทัด `puts x` จะได้ค่าออกมาเป็น `3` เพราะเราทำการประกาศซำ้หลายครั้ง ทำให้ค่าเดิมถูกล้างไป และครั้งสุดท้ายที่ประกาศคือ `x = 3`

นอกจากนี้เรายังสามารถใช้ค่าจากตัวแปรเดิมในทางด้านขวา เพื่อกำหนดค่าใหม่ได้อีกด้วย

{% embed url="<https://repl.it/@narze/variables-methods-redeclare-1?lite=true>" %}

เมื่อถึงบรรทัด `puts x` จะได้ค่าออกมาเป็น `6` ถ้าเราแจกแจงแต่ละบรรทัด `x` จะถูกเปลี่ยนค่าดังนี้

* `x = 1` ทำให้ `x` มีค่าเป็น `1`
* `x = x + 2`เป็นการประกาศ `x` ใหม่ แต่จากบรรทัดที่แล้ว `x` มีค่า `1` ทำให้ในบรรทัดนี้ `x` มีค่าเป็น `1 + 2` เท่ากับ `3`
* `x = x + 3` เป็นการประกาศ `x` ใหม่อีกครั้ง แต่จากบรรทัดที่แล้ว `x` มีค่า `3` ทำให้ในบรรทัดนี้ `x` มีค่าเป็น `3 + 3` เท่ากับ `6`

## แบบฝึกหัด การใช้ตัวแปร

โจทย์ : มีตะกร้าผลไม้ทั้งหมด `5` ใบ ใบหนึ่งมีแอปเปิล `4` ลูก แต่มีแอปเปิลเสียไป `3` ลูกจากทั้งหมด จงหาว่าเหลือแอปเปิลที่ยังไม่เสียกี่ลูก ให้โปรแกรมตอบว่า `เหลือแอปเปิล 17 ลูก` โค้ดที่ให้จะยังมี Error อยู่ จงแก้โค้ดให้ทำงานได้และตอบคำถามได้ถูกต้อง โดยการสร้างตัวแปร `a, b, c และ d`

{% embed url="<https://repl.it/@narze/variables-practice?lite=true>" %}

ดูเฉลยได้ในบทถัดไป


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.monosor.dev/courses/ruby/variables.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
