Function declaration style and variable scope problem

3 Comments

เป็นปัญหาที่ยังไม่สามารถทำให้เกิดขึ้นอีกในโค้ดแบบอื่นได้ แต่เอามาเขียนไว้ก่อนเพราะมันสร้างความปวดหัวให้กับคนเขียน Javascript มาก่อนมากมาย และไม่รู้จะเจอมันอีกทีเหมื่อไหร่ แต่ไม่สามารถเอาโค้ดต้นฉบับทั้งก้อนมาใส่ในนี้ได้ เลยขอแค่เล่าแล้วเอา stacktrace มาแปะใส่ไว้ละกัน

เหตุการณ์เริ่มต้นเกิดจาก @pitiphong_p เจอบั๊กหนึ่งที่ไม่รู็จะแก้อย่างไรเข้าเพราะใน Flash Builder Debugger บอกว่าตัวแปรต่างๆ มีค่าครบสมบุรณ์หมด แต่ error บอกไม่สามารถหาตัวแปรนั้นได้

[Fault] exception, information=TypeError: Error #1010: A term is undefined and has no properties.
Fault, CheckboxListRenderer.as:21
 21            data.selected = checkbox.selected
(fdb) bt
#0   this = [Object 32588233, class='global'].<anonymous>(event=[Object 659079665, class='flash.events::Event']) at CheckboxListRenderer.as:21
#1   EventDispatcher/dispatchEventFunction() at <null>:0
#2   this = [Object 655130785, class='mx.controls::CheckBox'].EventDispatcher/dispatchEvent(_arg1=[Object 659079665, class='flash.events::Event']) at <null>:0
#3   this = [Object 655130785, class='mx.controls::CheckBox'].UIComponent/dispatchEvent(event=[Object 659079665, class='flash.events::Event']) at UIComponent.as:9440
#4   this = [Object 655130785, class='mx.controls::CheckBox'].Button/http://www.adobe.com/2006/flex/mx/internal::setSelected(value=true, isProgrammatic=false) at Button.as:1204
#5   this = [Object 655130785, class='mx.controls::CheckBox'].Button/clickHandler(event=[Object 591642521, class='flash.events::MouseEvent']) at Button.as:2798

ตอนแรกก็พยายามคาดเดาปัญหาไปต่าง ๆ อาจเกิดจากการ bind ตัวแปรผิดที่ หรือตอนกำหนดค่าผิด แต่ถ้าอย่างนั้น ทำไมตอน debug ถึงสามารถเอาค่าออกมาดูได้หละ ลองดูโค้ดเจ้าปัญหาซักนิดก่อนละกัน

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package sample
{
  import mx.binding.utils.BindingUtils
  import mx.containers.HBox
  import mx.controls.Alert
  import mx.controls.CheckBox
  import mx.core.IFactory
 
  import flash.events.Event
 
  public class CheckboxListRenderer extends HBox {
 
    [Bindable]
    public var listRenderer:IFactory
 
    public var checkbox:CheckBox = new CheckBox()
 
    private var instance:*
 
    private var checkboxChange = function(event:Event):void {
      if (data.hasOwnProperty('selected')) {
        data.selected = checkbox.selected
      }
    }
 
    public override function set data(item:Object):void {
      super.data = item
      if (item && item.hasOwnProperty('selected')) {
        checkbox.selected = item.selected
      }
    }
 
    protected override function createChildren():void {
      super.createChildren()
      addChild(checkbox)
 
      if (listRenderer != null) {
        instance = listRenderer.newInstance()
        addChild(instance)
      }
      trace("Checkbox list renderer created children")
    }
 
    protected override function commitProperties():void {
      super.commitProperties()
      horizontalScrollPolicy = "off"
      verticalScrollPolicy = "off"
 
      // Handle change in targeting phase for changing data selected flag.
      checkbox.addEventListener(Event.CHANGE, checkboxChange)
 
      BindingUtils.bindProperty(instance, "data", this, "data")
    }
 
  }
}

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

20
21
22
23
24
    private var checkboxChange = function(event:Event):void {
      if (data.hasOwnProperty('selected')) {
        data.selected = checkbox.selected
      }
    }

เป็น

20
21
22
23
24
    private function checkboxChange(event:Event):void {
      if (data.hasOwnProperty('selected')) {
        data.selected = checkbox.selected
      }
    }

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

Vietnam Trip

No Comments

เข้าใจตรงกัน?

3 Comments

ทำงานมาเกือบสามปี ประชุมมาก็หลายครั้ง จนวันนี้ถึงได้คิดอย่างจริงจังว่า ที่คุยๆ กันเนี๊ยะ มันเข้าใจตรงกันหรือป่าว มันเป็นสิ่งที่กวนใจจนทำให้ไปสมัครเรียน ป.โท เพื่อหวังจะได้คำตอบนี้ และหาวิธีที่จะทำให้มันตรงกัน(ซึ่งก็ไม่รู้จะได้คำตอบหรือป่าว)

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

จากรูป ปัญหาที่พูดจบตอนแรกจนทุกคนเข้าใจแล้วคือ A และกำลังหาวิธีแก้ปัญหากัน แล้วก็มีคนพูดถึงวิธีแก้ปัญหาโดยใช้วิธี C ซึ่งในหัวก็อาจจะมี B มาก่อนแล้วถึงได้เสนอ C ขึ้นมา ส่วนคนที่สองก็อาจจะมีความรู้ที่คล้ายกัน แต่อาจจะไม่เหมือนกับ คนแรกซะทีเดียว แต่สุดท้ายคือได้ C เหมือนกัน แต่คนสุดท้ายนี่สิ ยังคิดอยู่ที่ A เพื่อให้ได้ B’ ออกมาอยู่เลย เพราะยังมองไม่ออกว่ามาเป็น C ได้ยังไง (ซึ่งก็คือคนที่เขียนบล๊อกนี้นี่เอง ^^!) คำถามคือ จะให้คนที่เสนอวิธี C มาแล้วทำให้คนสุดท้ายรู้ได้ไง และเห็นภาพเหมือนกันหมด

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

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

Older Entries