String Replace in Objective-C

เริ่มต้นด้วยการสร้างรายการตัวอักษรที่ไม่ต้องการ เนื่องจากทำงานกับ deviceToken เลยมีตัวอักษรที่ไม่ต้องการ 3 ตัว ได้แก่ “<", " ", ">” ก็สร้างชุดของตัวอักษรด้วย NSCharacterSet จะได้ว่า

NSCharacterSet *unwantedCharactersInDeviceToken = [NSCharacterSet characterSetWithCharactersInString:@"< >"];

ตอนนี้เราจะได้ชุดตัวอักษรที่ไม่ต้องการเรียบร้อยแล้ว (ตัวแปร unwantedCharactersInDeviceToken) ถัดไปคือการสร้าง NSArray จากข้อความที่เราสนใจ โดยใช้ชุดของตัวอักษรเป็นตัวแบ่ง จะได้ว่า

NSArray *filteredPharses = [[NSString stringWithFormat:@"%@", deviceToken] componentsSeparatedByCharactersInSet:unwantedCharactersInDeviceToken];

โดยที่ filteredPharses คือ ความความที่ถูกแบ่งออกเป็นช่วง ตามตำแหน่งที่พบตัวอักษรที่เราไม่ต้องการ

สุดท้าย คือการรวมเอาข้อความที่แบ่งไว้ด้วยตัวอักษรที่เราไม่ต้องการให้เป็น ข้อความ (NSString) ตามเดิม จะได้ว่า

NSString *finalJoinedMessage = [filteredPharses componentsJoinedByString:@""];

โค้ดสำเร็จรูปจะหน้าตาประมาณนี้

NSCharacterSet *unwantedCharactersInDeviceToken = [NSCharacterSet characterSetWithCharactersInString:@"< >"];
NSString *finalJoinedMessage = [[[NSString stringWithFormat:@"%@", deviceToken] componentsSeparatedByCharactersInSet:unwantedCharactersInDeviceToken] componentsJoinedByString:@""]];

ปล. เขียนไว้อ่านเองกันลืม

Google Maps V3 Introduction

ก่อนหน้านี้เคยเขียนวิธีการนำเอา Google Maps มาใช้งานกับเว็บไซต์ด้วยกัน 2 ตอน (1, 2) ตอนที่เขียนไปนั้น Google Maps เวอร์ชั่น 2.x ปัจจุบันอยู่ในสถานะ deprecated หรืออยู่ระหว่างการเลิกใช้งานนั้นเอง โดยตอนนี้ Google Maps เองก็พยายามเข็ญให้นักพัฒนาขยับไปใช้ Google Maps เวอร์ชั่นปัจจุบันคือเวอร์ชั่น 3 หรือเรียกสั้นๆ ว่า V3 ซึ่งการเรียกใช้งานนั้นง่ายกว่าเวอร์ชั่นเก่ามาก อย่างแรกที่เห็นได้ชัดคือเราไม่จำเป็นต้องสมัครเพื่อขอ API Key สำหรับใช้ดาวน์โหลด Google Maps Library อีกต่อไปแล้ว และการกำหนดค่าทั้งหมดใช้การกำหนดค่าผ่าน Object ที่เข้าใจได้ง่ายกว่าเวอร์ชั่นเก่ามาก
Continue reading

Unix Environment Variables

เรื่องหนึ่งใน Linux และ Linux Clone ที่สำคัญ คือ การเพิ่ม Environment Variable เป็นวิธีที่ทำให้ผู้ใช้สามารถสร้างตัวแปรขึ้นมาให้ OS รู้จัก จากนั้นจึงใส่ค่าที่ผู้ใช้ต้องการลงไป ส่วนมากค่าในตัวแปรมักจะเป็น path ที่ชี้ไปยังไดเร็คทอรี่ตามที่ต้องการ ประโยชน์เพื่อให้สามารถอ้างค่านี้ได้จากทุกที่ใน Terminal ซึ่งนั้นก็ช่วยทำให้ลดความผิดพลาดในการพิมพ์ทุกครั้งที่จะใช้งานได้ อีกส่วนหนึ่งเป็นการสะดวกสำหรับการนำไปใช้ในกรณีอื่นๆ เพราะผู้ใช้เพียงแค่เปลี่ยนค่าของตัวแปรเท่านั้นไม่จำเป็นต้องเปลี่ยนค่าทุกๆ ที่ที่มีการอ้างถึง

การสร้าง Environment Variable มีอยู่ด้วยกัน 2 วิธี ได้แก่

  1. วิธีการสร้างตัวแปรแบบชั่วคราว วิธีการนี้จะมีผลเฉพาะกับ Terminal ที่เราใช้งานใน session นี้เท่านั้น เพียง Terminal เดียว ไม่ส่งผลไปยัง Terminal อื่น ซึ่งแน่นอนว่าหากปิด Terminal ที่สร้างค่านี้ขึ้นมา ค่าดังกล่าวจะหายไปทันที วิธีการสร้างนี้ ทำได้โดยใช้คำสั่ง “export” ที่ shell prompt ดังนี้

    $ export ANDROID_HOME="/path/to/android_sdk_2.3"
    $ export PATH=$PATH:$ANDROID_HOME/platform-tools

    จากตัวอย่างด้านบน ($ หมายถึง shell promt) คือการสร้างตัวแปรชื่อ ANDROID_HOME ขึ้นมา (ชื่อตัวแปรขึ้นอยู่กับว่าเราจะกำหนด) จากนั้นกำหนดค่าให้เป็น “/path/to/android_sdk” ซึ่งเป็น absolute path ชี้ไปยังไดเร็คทอรี่ที่เก็บ Android SDK ภายในเครื่องเรา และบรรทัดถัดมาคือการทำให้เราสามารถใช้คำสั่งต่างๆ ที่อยู่ภายในไดเร็คทอรี่ platform-tools ได้โดยไม่ต้องอ้างด้วย absolute path ตลอดเวลา โดยการเพิ่มค่า “/path/to/androd_sdk_2.3/platform-tools” ต่อท้ายค่าในตัวแปร PATH ซึ่งตัวแปร PATH เป็นตัวแปรของ OS เมื่อเราใช้คำสั่งต่างๆ เช่น ‘ls’ OS จะไปค้นหาคำสั่งเหล่านั้นตามค่า (ไดเร็คทอรี่) ที่ระบุไว้ในตัวแปร PATH ซึ่งหากต้องการเพิ่มมากกว่า 1 ชุด ให้ค่ันด้วยเครื่องหมาย “:” เพื่อเป็นการแบ่งชุดข้อมูลที่ต้องการเพิ่มเข้าไปในตัวแปร PATH ซึ่งเครื่องหมายนี้จะต่างกันไปตาม OS เช่น Windows จะใช้เครื่องหมาย “;” สำหรับคั่นชุดข้อมูล

  2. วิธีการสร้างตัวแปรแบบถาวร จะว่าถาวรก็ไม่ถูกนักเพราะเราสร้างมารถแก้ไข และสั่งเปลี่ยนแปลงค่าของตัวแปรนั้นได้ตลอดเวลา วิธีการนี้ต่างจากวิธีการด้านบนคือค่าที่กำหนดจะคงอยู่เสมอถึงแม้จะปิด Terminal ไปแล้วก็ตาม นอกจากนั้นยังส่งผลไปกับทุกๆ Termimal อีกด้วย ซึ่งวิธีการคือเพิ่มคำสั่งด้านบนในข้อ 1 เข้าไปในไฟล์ .profile (อยู่ที่ home directory – ~/.profile) แต่หากไฟล์นี้ไม่มีก็ไม่ต้องตกใจ เพราะเราสามารถสร้างมันได้ ด้วยคำสั่ง

    $ touch ~/.profile

    คำสั่งด้านบนเป็นการสร้างไฟล์ชื่อ .profile ขึ้นภายใน home directory หากใช้คำสั่ง ‘ls’ จะไม่เห็นไฟล์นี้ เนื่องจากไฟล์ที่ขึ้นต้นด้วยเครื่องหมาย ‘.’ จะถูกซ่อนไว้ หากต้องการให้แสดงไฟล์ .profile ให้เพิ่ม ‘-a’ ต่อท้ายลงไปเพื่อแสดงไฟล์ทั้งหมด

    $ ls -a ~

    จากนั้นก็เลือก editor ที่เหมาะมือสักตัวเอามาช่วยในการแก้ไขค่าไฟล์ “.profile” โดยการแก้ให้เพิ่มค่าด้านล่างนี้ลงไป (ตัวอย่างเท่านั้น เปลี่ยนแปลงได้ตามชอบใจ)

    ANDROID_HOME="/path/to/android_sdk_2.3"
    PATH=$PATH:$ANDROID_HOME/platform-tools

    ผลลัพธ์ที่ได้จาก script ด้านบนจะเป็นเหมือนกับวิธีการในข้อ 1 หากแต่ต่างกันที่วิธีการด้านบนสามารถอ้างถึงค่า $ANDROID_HOME ได้ทันที แต่สำหรับข้อ 2 นี้ จำเป็นต้องสั่งเปลี่ยนแปลงค่าโดยอาศัยค่าที่อยู่ภายใน .profile ด้วยคำนั่ง source ดังนี้

    $ source ~/.profile

    โดยที่การใช้คำสั่ง source นี้ ทำเมื่อต้องการสั่งให้ปรับปรุงค่า Evironment Variable ที่กำหนดไว้ในไฟล์ .profile โดยที่ครั้งต่อไปหากเราเปิด Terminal ขึ้นมาใหม่ ค่าที่กำหนดไว้ใน ~/.profile ก็จะถูกอ่านขึ้นมาอัตโนมัติ

หลังจากข้อ 1 หรือ ข้อ 2 (ควรเลือกวิธีใดวิธีหนึ่งสักวิธี มิเช่นนั้นจะงงเอง) สามารถทดสอบการใช้คำสั่ง adb (เป็นคำสั่งที่อยู่ภายใน Android SDK) หากถูกต้องจะได้ผลดังรูป

ADB Command

PHPUnit Setup

PHPUnit เป็น Unit Test Framework สำหรับ PHP ใครใช้ JUnit มาแล้วก็อารมณ์เดียวกัน แค่เปลี่ยนจาก Java มาเป็น PHP

ก่อนอื่น ผมติดตั้งใน Mac OS X วิธีคงไม่ต่างกันมากนักกับ Linux แต่สำหรับ Windows อันนี้ไม่แน่ใจครับ เพราะเลิกใช้นานแล้ว

วิธีการติดตั้ง

  1. ให้แน่ใจว่าใช้คำสั่ง php ที่ terminal ได้
  2. PHPUnit ต้องการ pear ด้วย สำหรับใครที่ใช้ Windows ก็ต้องโหลดมาเพิ่ม ได้ที่ pear.php.net ส่วน Linux และ OS X ไม่ต้องเพราะมีแล้ว
  3. โหลด PHPUnit จาก pear.phpunit.de/get เลือกเอาตามชอบครับ ผมเลือกเป็น PHPUnit-3.4.9
  4. ไฟล์ที่ได้จะเป็นไฟล์ PHPUnit-x.x.x.tgz ใช้คำสั่งด้านล่างเพื่อแตกไฟล์ออก
    tar xzf PHPUnit-x.x.x.tgz
    จะได้โฟล์เดอร์ PHPUnit-x.x.x
  5. ในโฟล์เดอร์ PHPUnit-x.x.x จะมีไฟล์ phpunit.php คือไฟล์ที่เราต้องการ เปลี่ยน phpunit.php -> phpunit ก็ได้ไม่มีปัญหา
  6. ในไฟล์ phpunit.php บรรทัดที่ 43 เพื่อใช้ได้แน่นอนให้เปลี่ยน dirname(__FILE__) เป็น '/path/to/PHPUnit-x.x.x'
  7. และเพื่อให้ใช้คำสั่งจากที่ไหนก็ได้ ก็แก้ไขค่าใน .profile นิดหน่อย
    # vi ~/.profile
    ...
    export PHPUNIT_HOME=/path/to/PHPUnit-x.x.x
    export PATH=$PHPUNIT_HOME:$PATH
    :wq
    # source ~/.profile
  8. ลองเขียนโปรแกรมเล็กๆ ทดสอบดู
    <?php
    # StackTest.php
    require_once 'PHPUnit/Framework.php';
    class StackTest extends PHPUnit_Framework_TestCase
    {
        public function testPushAndPop()
        {
            $stack = array();
            $this->assertEquals(0, count($stack));
        }
    }
    
  9. จะได้ผลลัพธ์ดังนี้ ถือว่าสำเร็จใช้ได้

    PHPUnit

    PHPUnit

ข้อมูลเพิ่มเติม: PHPUnit Book [PDF]

แสดงหัวตารางซ้ำ

บันทึกความจำกันอีกตอนหนึ่งเพราะช่วงนี้ต้องใช้ OpenOffice.org (OO.o) อย่างหนักเมื่อก่อนไม่ค่อยได้ใช้มากเท่าไหร่นักอย่างมากก็พิมพ์งานนิดหน่อย แต่ช่วงนี้เริ่มต้องใช้รูปแบบที่ซับซ้อนขึ้น ตอนนี้กว่าจะหาเจอก็นานอยู่เหมือนกัน หรืออีกเหตุผลหนึ่งก็เพราะไม่คุ้นกับ OO.o เท่าไหร่นัก

ข้อมูลปริมาณมาก

รูปที่ 1: ข้อมูลปริมาณมาก


เมื่อข้อมูลมีความยาวเกินกว่า 1 หน้า

รูปที่ 2: เมื่อข้อมูลมีความยาวเกินกว่า 1 หน้า

การสั่งให้แสดงหัวตารางซ้ำอัตโนมัติเป็นฟังก์ชั่นที่สำคัญอีกฟังก์ชั่นหนึ่งเพราะช่วยให้ทำงานกับตารางที่มีข้อมูลที่มีความยาวหลายหน้าได้ง่ายและสะดวกมากยิ่งขึ้น อย่างเช่นในตัวอย่างด้านบน ข้อมูลมีความยาวมากกว่าที่จะใส่ในหน้ากระดาษแผ่นเดียวได้ วิธีการแก้ไขของผมเองคือแยกตารางส่วนที่เกินออกมาแล้วค่อยใส่หัวตารางใหม่ แต่ปัญหาจะเกิดขึ้นเมื่อต้องการเปลี่ยนแปลงหัวตาราง ซึ่งมันจะไม่ใช่ภาระเลยหากมีแค่เพียงตารางเดียวหรือ 2 ตาราง และหากมีการเปลี่ยนแปลงเนื้อหาภายในตารางที่ส่งผลให้ความยาวของตารางก่อนหน้าเปลี่ยนไปก็จะส่งผลกระทบไปสู่ตารางถัดไปอย่างหลีกเลี่ยงไม่ได้

Table

รูปที่ 3: Table


Table > Table Properties...

รูปที่ 4: Table > Table Properties...

ดังนั้นวิธีแก้ไขที่เจอก็คือกำหนดให้แสดงหัวตารางซ้ำ สามารถเข้าไปกำหนดค่าได้ 2 วิธีคือ 1 เมื่อคลิ้กที่ตารางจะมีแถบเครื่องมือ Table ดังเช่นรูปที่ 3 จากนั้นคลิ้กที่ปุ่มที่อยู่ในกรอบสีแดง และวิธีที่ 2 คือจากเมนู Table เลือก Table Properties... ดังรูปที่ 4

Table Format | Table Flow > Repeat Heading

รูปที่ 5: Table Format | Table Flow > Repeat Heading

จะได้หน้าต่าง Table Format ดังรูปที่ 5 จากนั้นเลือกที่แถบ Table Flow และคลิ้กเลือกที่ Repeat Heading และเปลี่ยนจำนวนแถวของหัวตารางที่ต้องการให้แสดงซ้ำตามต้องการจากนั้นจะได้ตารางดังรูปที่ 6 ซึ่งหากแก้ไขหัวตารางในรูปที่ 6 นี้ก็จะส่งผลไปยังหัวตารางที่เห็นในรูปที่ 1 ด้วย

Repeat Table Heading

รูปที่ 6: Repeat Table Heading

ฟังก์ชั่นนี้เป็นฟังก์ชั่นพื้นฐานที่พบได้ในโปรแกรม Word Processing ทั่วไป ทั้ง MS Word, และ Pages ครับ

โปรแกรมที่ใช้: OpenOffice.org 3.1.1 Writer

Apache Ant in Actions I – Overview

ช่วงนี้ได้มีโอกาสจับงาน Java ที่ต้องมี Source ไฟล์มาเกี่ยวข้องด้วยเยอะ ไอ้การจะมานั่งจัดการไฟล์จำนวนมากด้วยมือก็เห็นจะไม่ใช่เรื่องดีเท่าไหร่ งานนี้ก็เลยต้องอาศัย Build Tools มาช่วยงานสักหน่อย ก็ได้แค่โปรแกรมที่ชื่อว่า Apache Ant หรือที่รู้จักกันดีและเรียกกันสั้นๆ ว่า Ant ตัวนี้สักหน่อย
Ant เป็นเครื่องมือที่ช่วยจัดการงานต่างๆ ที่เราต้องทำเข้าไว้ด้วยกัน ในรูปแบบของชุดคำสั่ง เทียบได้กับ make ใน unix ซึ่งข้อดีของ Ant คือ มันเป็น OS Independent ที่เขียนขึ้นมาด้วย Java ทำให้เขียนโปรแกรมแล้วนำคำสั่งชุดคำสั่งนี้ไปทำงานหรือแก้ไขที่ได้ก็ได้โดยให้ผลลัพธ์ (จาก Ant) เช่นเดียวกัน

Build File

คือชุดคำสั่งของ Ant ที่เราเขียนและกำหนดไว้เพื่อให้ Ant ทำตาม อยู่ในไฟล์ ‘build.xml’ (เป็นค่า default) จะเรียกว่า build file มีโครงสร้างตามรูปด้านล่าง ภายใน build file ดังกล่าวจะหมายถึง 1 โปรเจ็คที่เรากำลังสนใจอยู่ ก่อนที่จะทำงาน เราอาจจะสร้างประกาศค่าต่างๆ ที่จำเป็นต้องใช้ในการทำงานไว้ในส่วนของ Property (Properties) จากนั้นจึงค่อยสร้างเป้าหมาย (target) สำหรับการทำงานไว้ เป็นกลุ่มๆ ส่วนตัวผมจะแบ่งไว้ให้เป็นเป้าหมายที่ย่อยที่สุดเท่าที่จะทำได้ เช่น สร้างโฟลเดอร์, โหลด dependency ไฟล์, compile ซอร์สโค้ด, สร้าง jar ไฟล์ และ deploy ลง Server เป็นต้น เพื่อให้ง่ายต่อการจัดการ งาน (Task) ที่ต้องทำภายใน Target อีกที ส่วนตัวแล้วชอบวางลำดับของ Target ไว้ตามลำดับการทำงานจากบนลงล่างเพื่อให้ง่ายตอนเขียน แต่ลำดับของ Target ภายใน build file ไม่มีผลกระทบต่อการทำงานใดๆ ของ Ant เลย แต่ Ant จะเริ่มการทำงานจาก default target ที่ระบุไว้ใน attribute ของแท็ก project

Apache Ant's Build File Structure

Apache Ant's Build File Structure

การทำงานของ Ant หากไม่ระบุ target ที่ต้องการ Ant จะเริ่มทำงานจากค่า default ในแท็ก project โดยก่อนการทำงานของ target ดังกล่าว Ant จะตรวจสอบว่า target นี้มี target อื่นที่ต้องทำก่อนหน้าหรือไม่ (Dependency Target – depends) เช่น หากต้องการสร้าง jar ย่อมต้องใช้ class ไฟล์ ที่ได้จากการ compile ซอร์สโค้ดล่าสุดซะก่อน หากเราระบุ target ดังกล่าวไว้ Ant จะทำหน้าที่ไปตรวจสอบว่าซอร์สโค้ดดังกล่าวถูก compile แล้วหรือยัง หากมีไฟล์ที่เปลี่ยนแปลงและยังไม่ได้ compile ก็จะทำให้อัตโนมัติ

หลังจากเสร็จการทำงานใน Dependency Target แล้ว Ant ก็จะเริ่มทำตาม Task ที่ระบุไว้ภายใน Target จากบนลงล่างตามลำดับ ซึ่งภายใน Target อาจจะใช้ Ant Call (<antcall … ) เพื่อเรียกการทำงานของ Target อื่นๆ ที่อยู่ภายใน build file ก็ได้ตามต้องการ

Official Site: http://ant.apache.org
Manual: http://ant.apache.org/manual/index.html

Subversion in Actions II

คราวที่แล้วเขียนเกี่ยวกับการใช้ Subversion (svn) เบื่องต้น ได้แก่ การสร้าง Repository, เพิ่มไฟล์เข้าสู่ index ใน working copies (add), และส่งเข้าสู่ Repository (commit) ส่วนตอนนี้ก็จะขอพูดส่วนเกี่ยวกับคำสั่งต่างๆ ที่เอาไว้ติดตามความเคลื่อนไหว และการเปลี่ยนแปลงของ Repository ครับ

ข้อมูลประจำรุ่น (log)

เป็นข้อมูลประจำสำหรับรุ่นนั่น เช่น Revision ผู้ commit วันเวลา จำนวนบรรทัดที่เปลี่ยนแปลง และบันทึกประจำรุ่น มีรูปแบบตามนี้ครับ

REVISION_NO | USER_NAME | DATE_TIME | LINE_CHANGED

MESSAGE_LOG

ตัวอย่างเช่น

  $ svn log file:///Users/sitdh/Repository/helloSVNServer
  ------------------------------------------------------------------------
  r2 | sitdh | 2009-09-10 00:40:52 +0700 (Thu, 10 Sep 2009) | 1 line

  Create Project
  ------------------------------------------------------------------------
  r1 | sitdh | 2009-09-09 21:56:38 +0700 (Wed, 09 Sep 2009) | 1 line

  test
  ------------------------------------------------------------------------

คำอธิบาย:

  • บรรทัดที่ 03 และ 07 คือ ข้อมูลประจำรุ่น
  • บรรทัดที่ 05 และ 09 คือ คำอธิบายการเปลี่ยนแปลงที่ผู้ commit เขียนอธิบายไว้

หมายเหตุ: ข้อมูลดังกล่าวเป็นข้อมูลที่ได้จาก Repository เนื่องจากเราระบุพาธไว้ด้านหลัง หากให้คำสั่ง svn log จะเอา log ที่อยู่ใน Working Copies มาแสดงแทน ซึ่งข้อมูลที่ได้อาจไม่ตรงกับ Repository วิธีแก้คือใช้คำสั่ง update เพื่อปรับปรุงข้อมูลให้ตรงกัน (Synchonize – sync) ระหว่าง Working Copies และ Repository

  $ svn update file:///User/sitdh/Repository/helloSVNServer
  At revision 3.

คำอธิบาย:

  • บรรทัดที่ 01 ใช้คำสั่งเพื่อ sync ข้อมูล หามีข้อมูลที่ไม่ตรงกับ Repository จะแสดงรายการเปลี่ยนแปลงด้านล้าง
  • บรรทัดที่ 02 เป็นบรรทัดที่บอก Revision ล่าสุดที่อยู่ใน Repository (HEAD Revision)

หาความแตกต่างระหว่างเวอร์ชั่น (diff)

ก่อนอื่นต้องทบทวนก่อนว่าในตัวอย่างของ blog ที่แล้วได้สร้างข้อมูลตัวอย่างและส่งเข้า Repository เรียบร้อยแล้ว (Revision 3 หรือ r3) จากนั้นได้แก้ไขข้อมูลในไฟล์ ‘index.php’ เล็กน้อย และ commit เข้าไปยัง Repository เรียบร้อยแล้ว (Revision 4 หรือ r4) ดังนั้นถ้าอยากรู้ว่าระหว่าง r3 และ r4 มีความแตกต่างตรงไหนบ้าง คำสั่งที่ช่วยได้ก็คือ diff ดังนี้

$ svn diff -r 3:4
Index: index.php
===================================================================
--- index.php	(revision 3)
+++ index.php	(revision 4)
@@ -1,3 +1,4 @@
-hello, world

\n"; + echo "

hope you like it

"; ?>

คำอธิบาย:

  • บรรทัดที่ 02 Index จะบอกว่าตอนนี้เปรียบเทียบไฟล์ไหนอยู่
  • บรรทัดที่ 04 – 05 กำหนดเครื่องหมายสำหรับ r3 แทนด้วย ‘-’ และ r4 แทนด้วย ‘+’ โดย ใช้บอกว่าบรรทัดไหนหายไปจาก r4 (-) และเพิ่มเข้ามาใน r4 (+) ถ้าบรรทัดไหนไม่เปลี่ยนแปลงก็จะไม่มีเครื่องหมายนำหน้า
  • บรรทัดที่ 07 – 08 คือ บรรทัดที่มีอยู่ใน r3 แต่หายไปจาก r4 (เครื่องหมาย - นำหน้า)
  • บรรทัดที่ 09 – 11 คือ บรรทัดที่เพิ่มเข้ามาใน r4
  • บรรทัดที่ 12 เป็นบรรทัดที่ไม่เปลี่ยนแปลง