Saturday, April 08, 2006

[Ingres] II7 port

ในคู่มือการต่อ jdbc ไปยัง database ingres
ระบุไว้ว่า port number มีค่า default เป็น 'II7'
ซึ่งทำให้ผมเกิดความสงสัยว่า มัน resolve ค่าเป็น integer อย่างไร
แรกสุดก็นึกว่าเป็น feature ของ unix
พยายามค้นใน google แต่ไม่พบ
สุดท้ายก็ไปเจอใน source code ของ ingres jdbc
private int getPort(String target) {
...
char c0 = port.charAt( 0 );
char c1 = port.charAt( 1 );
char c2 = (port.length() == 3) ? port.charAt( 2 ) : '0';

if (
Character.isLetter( c0 ) &&
Character.isLetterOrDigit( c1 ) &&
Character.isDigit( c2 )
)
{
c0 = Character.toUpperCase( c0 );
c1 = Character.toUpperCase( c1 );

return( 1 << 14 | (c0 & 0x1f) << 9 |
(c1 & 0x3f) << 3 | (c2 & 0x07) );
}

...
}

เวลาเราลง Ingres, จะต้องมีการระบุ Installation code
ซึ่งใช้แยก instance, configuration ของ Database Server ออกจากกัน
(1 เครื่อง, start ได้หลาย installation พร้อมๆกัน)
ค่า default ของ Installation code ก็คือ 'II'
นี่จึงเป็นที่มาของ port 'II7'
ถือว่าเป็น idea ที่ดีเหมือนกัน เพราะไม่ต้องจำเลข
เปลี่ยนมาจำตัวหนังสือแทน

Note: เลข 7 มาจากไหน?

Related link from Roti

[Ruby] แปลง float ให้อยู่ในรูป Single precision (IEEE 754)

วันนี้นั่งทดลอง convert Ingres JDBC Library ซึ่งเขียนด้วย java
ให้เป็น ruby code,
ไปเจอ code ของ Java อยู่อันหนึ่ง
Float.floatToIntBits(fValue);

method นี้ทำหน้าที่แปลง float value ให้อยู่ในรูป Single precision

ใน ruby ถ้าต้องการทำแบบเดียวกัน
[fValue].pack("g")


ใน ruby การแปลงเป็น binary format จะใช้
method pack ใน class Array
ส่วนการแปลงกลับจาก binary form ก็จะใช้
method unpack ใน class String

กรณีที่เราต้องเขียนโปรแกรมระดับ Network protocol,
bit-struct เป็น library ตัวหนึ่งที่ช่วยให้เรา pack กับ unpack ได้ง่ายขึ้น
ตัวอย่าง code ของ bit-struct
class IP < BitStruct
unsigned :ip_v, 4, "Version"
unsigned :ip_hl, 4, "Header length"
unsigned :ip_tos, 8, "TOS"
unsigned :ip_len, 16, "Length"
...
octets :ip_src, 32, "Source addr"
octets :ip_dst, 32, "Dest addr"
rest :body, "Body of message"
end

ip = IP.new
ip.ip_v = 4
ip.ip_hl = 5
ip.ip_tos = 0
...
p.ip_src = "192.168.1.4"
ip.ip_dst = "192.168.1.255"
ip.body = "This is the payload text."


Note: สำหรับคนที่ไม่คุ้นกับ ruby, unsigned ที่เห็นใน source ข้างบน
ไม่ใช่การประกาศ datatype แบบใน java หรือ c
แต่เป็นการเรียกใช้ class method เพื่อ dynamic generate instance method

Related link from Roti

Wednesday, April 05, 2006

[Rails] โครงสร้างภายในของ ActiveRecord ในส่วน attributes

สมมติเรามี table products ซึ่งมี definition ดังนี้
+-------+---------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+---------------+------+-----+---------+-------+
| id | int(11) | YES | | NULL | |
| name | varchar(120) | YES | | NULL | |
| price | decimal(10,2) | YES | | NULL | |
+-------+---------------+------+-----+---------+-------+

เวลาที่เราใช้คำสั่ง find เพื่อค้นหาข้อมูล
@product = Product.find(1)

ActiveRecord จะ delegate การทำงานต่อไปยัง database adaptor ที่เรากำหนด
ซึ่ง adpater จะ fetch ข้อมูลจาก database แล้วแปลงให้อยู่ในรูป hash table
{"name"=>"test", "price"=>"11.00", "id"=>"1"}

ให้สังเกตว่า datatype จะเป็น string หมด
Note: ต้องใช้ debugger เข้าไป step ดู จึงจะเห็น, ถ้าใช้วิีธี print debug
โดยเรียกใช้ method attributes จะเห็นเป็น datatype ที่
activerecord ทำการ convert ให้แล้ว


จากนั้น finder ก็จะทำการ new Model Object ขึ้นมา
และกำหนด instance variable @attributes
ให้มีค่าเท่ากับ hash result ที่ได้จาก database adaptor

การ access object attribute ปกติเราจะใช้คำสั่งแบบนี้

old_price = @product.price
@product.price = 12

ในครั้งแรกที่เราเรียกใช้ method price หรือ price=
method พวกนี้จะยังไม่มีอยู่จริง
แต่ Activerecord จะใช้ method method_missing ดักไว้
(method_missing เป็นกลไกของ ruby ที่ไว้ support กรณี send message ไปยัง method ที่ไม่ได้ define ไว้)
และทำการ manipulate ค่าใน @attributes โดยใช้ method
read_attribute กับ write_attribute
Note: method read_attribute, write_attribute
มีคุณสมบัติพิเศษ ก็คือ มันช่วยในการ convert datatype ให้ด้วย
ถ้าเราเรียกใช้ @product.read_attribute('price')
ผลลัพท์ที่ได้กลับมา จะอยู่ในรูปของ Float value

หลังจากนั้น activerecord ก็จะ check ว่า flag generate_read_methods
เป็น true หรือไม่ ถ้าใช่ มันก็จะทำการ generate method ให้เราอัตโนมัติ
ซึ่งมีผลให้การ access ครั้งต่อไปมี performance ที่ดีขึ้น

เวลาที่เรานำ activerecord model ไปใช้งานร่วมกับ UI layer
ค่าที่ pass มาจาก form เรามักจะกำหนดให้อยู่ในรูป hash table
ผลที่ได้ ก็คือเราสามารถนำ hashtable นั้น มา update model
ของเราได้โดยตรง (เพราะ internal structure ของ model
ก็เป็น hash เหมือนกัน)

Related link from Roti

Git (Version Control)

Git - Tree History Storage Tool

GIT is a version control system designed to handle absolutely massive projects with speed and efficiency; it is used mainly for various open source projects, most notably the linux kernel.


gitk screenshot (repository browser)

Related link from Roti

Tuesday, April 04, 2006

[clisp, perl] dynamic scope

เคยเขียนกรณี Dynamic scope & Static scope ไปที
ตอนนั้นระบุว่า scheme, javascript เป็น static scope
ส่วน ruby เป็น dynamic scope

วันนี้มาดู clisp บ้าง
clisp สามารถเลือกได้ว่าจะให้เป็น static หรือ dynamic scope
โดย default จะเป็น static scope

(setq x 5)
(defun get-x () x)
(let ((x 12)) (get-x)) ;; => 5

ผลลัพท์ที่ได้จากคำสั่งที่ 3 , get-x จะได้ค่า 5 ออกมา
(ซึ่งเราเรียกว่า static scope)
แต่ถ้าเป็น dynamic scope, get-x จะต้องได้ค่า 12 ออกมา

ใน clisp เราสามารถกำหนดให้ตัวแปรเป็น dynamic scope ได้
โดยใช้คำสั่ง defvar
(defvar y 5)
(defun get-y () y)
(let ((y 12)) (get-y))


perl ก็สามารถเป็นได้ทั้ง static หรือ dynamic scope
กรณี static
$x = 5;
sub get_x {
print "x = $x";
}
sub test_static {
my $x = 12;
get_x();
}
test_static # => x = 5

ถ้าต้องการ dynamic ก็จะเป็นแบบนี้
$y = 5;
sub get_y {
print "y = $y";
}
sub test_dynamic {
local $y = 12;
get_y();
}
test_dynamic; # => y = 12

Related link from Roti

Monday, April 03, 2006

[ruby] instance variable อีกที

object ทุก object ใน ruby สามารถมี instance variable ของตัวเองได้
2.instance_variable_set '@x', 1

2.
instance_variable_get '@x' # => 1
4.instance_variable_get '@x' # => nil
(4 - 2).instance_variable_get '@x' # => 1

บรรทัดที่น่าสนใจคือ (4 - 2).instance_vairable_get '@x'
ถ้าจิตนาการ การทำงานภายในของ interpreter ณ บรรทัดนั้น ดู
  • ขั้นแรกก็ต้อง new instance fixnum ค่าเป็น 4
  • จากนั้นก็ new instance fixnum ค่าเป็น 2
  • เรียกใช้ method - ของ instance 4 โดยมี parameter เป็น instance 2
  • เรียกใช้ method instance_variable_get บน instance fixnum 4

ปัญหาเกิดที่ขั้นที่ 3 ว่ามันเรียก instance_variable_get บน object คนละตัวกับ object 2
แล้วทำไมค่ามันยังออกมาถูก มันมีกลไกพิเศษอะไรตรงไหน

ลองเปลี่ยนจาก fixnum เป็น String ดูบ้าง
"hello".instance_variable_set '@x', 1
puts "hello".instance_variable_get '@x' # => nil
x = "hello"
x.instance_variable_set '@x', 1
puts x.instance_variable_get '@x' # => 1

จะเห็นได้ว่า instance_variable ของ 2 กับ "hello" มีพฤติกรรมไม่เหมือนกัน

ข่าวดี ไม่ใช่ทุกอย่างใน ruby ที่เป็น object อย่างเป็นทางการ
คำว่า object อย่างเป็นทางการ ก็คือ มี structure เป็นเรื่องเป็นราว เช่นมี id, methods, attributes
ถ้าจะให้ยกตัวอย่างชัดๆ ต้องดูที่ implementation ของ ruby ที่ใช้ c เขียน
struct RObject {
struct RBasic basic;
struct st_table *iv_tbl;
};

แต่ก็มีพวก special object ที่ไม่ได้ใช้ struct ในการ represent
object ต่อไปนี้ ใช้ unsigned long ตัวเดียวในการ implement object (แทนที่จะใช้ struct)
  • small integers
  • symbols
  • true
  • false
  • nil
  • Qundef (อันนี้ไม่รู้ว่ามันคืออะไร)

เหตุผลที่ต้อง implement special object แบบนี้ ก็คือเรื่อง performance
(เหมือนกับ java ที่ต้องมี primitive datatype)

ที่นี้ ruby สามารถให้ค่า instance_variable ที่ถูกต้อง ในกรณี fixnum ได้อย่างไร
ที่เป็นเช่นนี้ ก็เพราะวิธีการ implement ของ ruby เป็นแบบนี้

/* file variable.c */
static VALUE
ivar_get(obj, id, warn)
VALUE obj;
ID id;
int warn;
{
VALUE val;

switch (TYPE(obj)) {
case T_OBJECT:
case T_CLASS:
case T_MODULE:
if (ROBJECT(obj)->iv_tbl && st_lookup(ROBJECT(obj)->iv_tbl, id, &val))
return val;
break;
default:
if (FL_TEST(obj, FL_EXIVAR) || rb_special_const_p(obj))
return generic_ivar_get(obj, id, warn);
break;
}
if (warn) {
rb_warning("instance variable %s not initialized", rb_id2name(id));
}
return Qnil;
}

จะเห็นว่ากรณีของพวก special object จะมีการใช้ generic_ivar_get
ซึ่ง function generic_ivar_get นี้จะไปค้นหาค่าจาก global hashtable ที่ share กันใช้ ระหว่าง special object
นี่เป็นสาเหตุให้ fixnum 2 สามารถเรียกใ้ช้ instace_variable_get แล้ว ยังได้ค่าเดิมกลับมา

ส่วนกรณี String, จริงๆแล้ว มันตก case เดียวกับ fixnum
แต่วิธีการ implement ของ String เป็นอีกแบบหนึ่ง
ลองดูตัวอย่างนี้
irb(main):001:0> 2.object_id
5
irb(main):002:0> (4-2).object_id
5
irb(main):003:0> "hello".object_id
175214
irb(main):004:0> "hello".object_id
169884

จะเห็นได้ว่า id ของ string มันเปลี่ยนไปทุกครั้ง
ดังนั้นการ lookup instance_variable ใน generic table ที่ต้องใช้ object_id เป็นตัวเปิด hashtable
ก็เลยไม่ได้ค่าเดิมออกมา

Related link from Roti

[ruby] instance variable ของใคร?

ลองดู code นี้แล้วทายสิว่า
ถ้าเราเรียก method x แล้วจะได้อะไรกลับมา

class Foo
@x = 1
def x
@x
end
end

f = Foo.new
f.x # => nil

ใน ruby, class ก็คือ object หนึ่ง(ไม่เหมือน java)
ดังนั้น @x ของเราก็ตือ instance variable ของ class Foo

class Foo
@x = 1
def initialize(value)
@x = value
end
def x
@x
end
def self.x
@x
end
end

f = Foo.new(8)
f.x # => 8
Foo.x # => 1

Related link from Roti

จริยธรรมของแท็กซี่

เมื่อวันเสาร์ ภรรยาผมนั่ง taxi ไปกับลูกชายตัวน้อย
taxi เอ่ยปากชวนคุย
"พรุ่งนี้ไปเลือกตั้งไหม"
แฟนผมก็ตอบสั้นๆ
"ไปค่ะ"

taxi เอ่ยต่อ "แล้วจะไปเลือกใคร"
แฟนผมเงียบไปพักใหญ่ก่อนตอบว่า
"ไม่บอกค่ะ เขาเตือนกันว่า ช่วงนี้เวลาขึ้น taxi ห้ามคุยเรื่องการเมือง
กลัวถูกไล่ลง"

taxi ก็หัวเราะ แล้วก็บอกว่า
"ผมเป็น taxi ที่มีจริยธรรมนะ
เด็ก,ผู้หญิง,คนแก่ ผมไม่ไล่ลงหรอก"

Related link from Roti

Sunday, April 02, 2006

ไชยันต์ ไชยพร


คำแถลง รศ. ดร. ไชยันต์ ไชยพร หัวหน้าภาควิชาการปกครอง
คณะรัฐศาสตร์ จุฬาลงกรณ์มหาวิทยาลัย

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

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

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

โดยขอปฏิเสธหน้าที่พลเมืองที่กำหนดไว้ในกฎหมายเลือกตั้ง เพื่อรักษาสิทธิเสรีภาพของผมโดยฉีกบัตรเลือกตั้งของผมเองในวันนี้ ซึ่งผมเห็นว่าเป็นหนทางเดียวที่รักษาสิทธิของผมไว้ไม่ให้ถูกบิดเบือนไปเป็นอื่นได้

โดยขอฝ่าฝืนกฎหมายเลือกตั้งมาตรา 108 “ผู้ใดจงใจกระทำด้วยประการใด ๆ ให้บัตรเลือกตั้งชำรุดหรือเสียหายหรือกระทำด้วยประการใด ๆ แก่บัตรเสียเพื่อให้เป็นบัตรที่ใช้ได้ ต้องระวางโทษจำคุกไม่เกินหนึ่งปี และปรับไม่เกินสองหมื่นบาท และให้ศาลสั่งเพิกถอนสิทธิเลือกตั้งมีกำหนดห้าปี”
คดีนี้ผมจะเรียนต่อเจ้าพนักงานว่า ผมขอสู้คดีในชั้นศาล โดยจะไม่ยอมรับการเปรียบเทียบปรับใดๆ โดยจะขอต่อสู้คดีนำสืบให้ศาลเห็นถึงการใช้อำนาจยุบสภาโดยบิดเบือนจากวิถีทางในรัฐธรรมนูญเป็นลำดับไป ทั้งหลักฐานการถือประโยชน์ทับซ้อนของนายกรัฐมนตรี หลักรัฐศาสตร์และนิติศาสตร์ว่าด้วยอำนาจยุบสภาของรัฐบาล กระบวนการเลือกตั้งที่ไม่โปร่งใสเป็นธรรม รวมทั้งขบวนการปิดกันข่าวสารทั้งมวล เพื่อประมวลให้ศาลเห็นได้ว่า การเลือกตั้งครั้งนี้เป็นวิธีการแสวงหาอำนาจ รักษาอำนาจของเผด็จการจำแลงอย่างชัดเจน การต่อสู้คดีของผมในครั้งนี้จะมี ศูนย์นิติศาสตร์ คณะนิติศาสตร์ มหาวิทยาลัยธรรมศาสตร์ รับเป็นทนายความ มีอดีตสมาชิกวุฒิสภา แก้วสรร อติโพธิ และเพื่อนคณาจารย์ร่วมคณะรับเป็นที่ปรึกษาคดี

ขอเรียนย้ำว่า ผมไม่มีความเจ็บป่วยทางจิต ไม่มีความหลงโลภ หรือโกรธเข้าครอบงำ ผมเพียงแต่ไม่ยอมให้ พ.ต.ท. ทักษิณ ชินวัตรและบริวาร พรากเสรีภาพที่ติดตัวผมและเป็นของผมมาแต่กำเนิดไป เท่านั้นเองจริงๆ

นายไชยันต์ ไชยพร
๒ เมษายน ๒๕๔๙

Related link from Roti