Saturday, May 13, 2006

อิีกหนึ่งฟางฝัน

พึ่งอ่านจบไป
"อีกหนึ่งฟางฝัน บันทึกแรมทางของชีวิต"
เป็นหนังสือของ จีรนันท์ พิตรปรีชา

เมื่อ 10 กว่าปีก่อน เคยติดตาม
งานของเสกสรรค์ ประเสริฐกุล
พอเล่มนี้ออกมา ก็เลยอยากอ่านมุมมองที่เป็นของภรรยาเขาบ้าง
ไม่ผิดหวังเลย
เขียนได้ดีมาก

เมื่อรู้ภูมิหลังบางอย่าง
ความซาบซึ้งกับ บทกวีใน "ใบไม้ที่หายไป" ก็เลยมีมากขึ้น

โคลนตมถมเท้าทับ
ทางเดินนับทุกก้าวนี้
รอยร่องของชีวี
ที่เรียนรู้สู้ฟาดฟัน

จัดเก็บสัมภาระ
เกิดเกะกะก็เลือกสรร
เหลือเพียงสิ่งสำคัญ
อันจะเอื้อเกื้อชีพใช้

คัดพืชเมล็ดพันธุ์
ซึ่งสีสันสวยสดใส
เพื่อหว่านเมื่อผ่านไป
ริมไหล่ทางอันย่างยาว

Related link from Roti

Code as Data

Don Box post ถึง new favorite feature ใน C#3.0
โดยยกตัวอย่าง scheme code ให้ดูด้วย
Expression<Func<int, int>> expr = a => a + 3;
Console.WriteLine(expr); // prints "a => Add(a, 3)"
Func<int, int> func = expr.Compile(); // LCG's an MSIL method from the expr
Console.WriteLine(func(4)); // prints "7"

(define expr '(lambda (a) (+ a 3)))
(display expr)
(define func (eval expr (scheme-report-environment 5)))
(display (func 4))


Patrick ตั้งข้อสังเกตว่า comparison มี flaws บางอย่าง

สุดท้าย Don ก็เลยเขียนอธิบายให้เห็นชัดๆว่า
ที่เขาต้องการเปรียบเทียบคืออะไร
Code and Data in C#

Related link from Roti

Firebug - new feature

version หน้าของ firebug จะมี debugger มาให้แล้ว
ถ้าอยากรู้ว่าหน้าตาเป็นอย่างไร ให้ดูที่นี่
An In-depth Look At The Future of Javascript Debugging With Firebug

Related link from Roti

Wednesday, May 10, 2006

Rails Reference

Related link from Roti

มาร์ติน วีลเลอร์

อ่าน สัมภาษณ์

Related link from Roti

Tuesday, May 09, 2006

Hibernate, Spring, open session in view

ถ้าใครใช้ Hibernate ใน web application มักจะพบเจอปัญหา LazyInitialize ทุกราย
ซึ่ง case classic ก็คือ
ใน data access layer มีการเปิด session และทำการ query ข้อมูล
จากนั้นก็ปิด session แล้ว return ข้อมูลกลับไปยัง UI
ซึ่งพอ jsp ทำการ render ข้อมูล
และเกิดไปแตะข้อมูลที่ยังไม่ได้ initialize
ก็จะเกิด LazyInitializeException ขึ้น
(แต่ถ้าเกิดการแตะข้อมูลที่ยังไม่ initialize ในขณะที่ session ยังเปิดค้างไว้อยู่,
Hibernate จะ initialize ข้อมูลให้โดยอัตโนมัต)

ทางแก้ทางหนึ่งก็คือโอนความรับผิดชอบในการเปิดปิด session
ไปให้กับ Servlet Filter เสีย

Spring ได้เตรียม Filter ที่ทำหน้าที่แบบนี้ไว้ให้แล้ว
ชื่อว่า OpenSessionInViewFilter

การ config ก็แค่เพิ่ม block นี้ลงใน web.xml
<filter> 
<filter-name>OpenSessionInViewFilter</filter-name>
<filter-class>org.springframework.orm.hibernate.support.OpenSessionInViewFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>OpenSessionInViewFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

การทำงานภายในของ OpenSessionInView ก็คือ
เมื่อเกิด request เข้ามา
มันจะทำการค้นหา SessionFactory จากใน Spring Context
โดยมันจะตั้ง Assumption ว่า มันจะค้นหา SessionFactory
จาก Bean ที่มีชื่อว่า sessionFactory
public static final String DEFAULT_SESSION_FACTORY_BEAN_NAME = "sessionFactory";

protected SessionFactory lookupSessionFactory() {

WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
return (SessionFactory) wac.getBean(getSessionFactoryBeanName(), SessionFactory.class);
}

จากนั้น มันก็จะทำการ สร้าง session และ bind session โดยเรียกใช้
TransactionSynchronizationManager.bindResource
ซึ่งจะทำการ put ค่า session นั้นเก็บไว้ใน ThreadLocal
session = getSession(sessionFactory);
TransactionSynchronizationManager.bindResource(sessionFactory,
new SessionHolder(session));

doFilter ...

TransactionSynchronizationManager.unbindResource(sessionFactory);


ที่นี้บางคนก็จะมีคำถามว่า แล้วเวลาเรียกใช้ session หล่ะ
มันจะเกิดอะไรขึ้น
ใน spring, เรามักใช้ HibernateTemplate เข้้ามาช่วยอยู่แล้ว
ซึ่ง HibernateTemplate เอง มันจะเรียกเปิด openSession
ซึ่งภายใน จะ delegate ต่อไปยัง SessionFactoryUtils
protected Session getSession() {

.. //another case

return SessionFactoryUtils.getSession(
getSessionFactory(),
getEntityInterceptor(),
getJdbcExceptionTranslator());

}

ถ้าตามไปดู code ใน SessionFactoryUtils ก็จะเห็นว่า
มีการใช้ TransactionSynchronizationManager
เข้าไปดึงค่า SessionHolder ที่ OpenSessionInView เป็นคนสร้าง
และเก็บไว้ใน ThreadLocal
private static Session getSession(
SessionFactory sessionFactory, Interceptor entityInterceptor,
SQLExceptionTranslator jdbcExceptionTranslator, boolean allowCreate)
throws DataAccessResourceFailureException, IllegalStateException {

SessionHolder sessionHolder = (SessionHolder)
TransactionSynchronizationManager.getResource(sessionFactory);

... // too much, just pretend that it not exist

return sessionHolder.getSession();

... // case for กรณีไม่ได้ใช้ filter
}


ถ้าสรุปง่ายๆ (ลอกจาก Configuring Hibernate, Spring and (MyFaces) JSF)
  • Sets up the Servlet filter that manages the Hibernate session
  • Associates a Hibernate session with the current thread assigned to the current request
  • Classes that use HibernateTemplate will access the same session by default
  • HibernateTemplate uses SessionFactoryUtils.getSession
  • SessionFactoryUtils.getSession uses existing Hibernate Session associated with the current thread

ง่ายๆเลย ไม่ต้องไปใล่ดู code ให้เสียเวลา

Related link from Roti

Monday, May 08, 2006

viminfo

เมื่อ vim ของผมเริ่มเปิด file ได้ช้าลง
ก็แสดงว่า ถึงเวลาที่จะลบ file viminfo ออกได้แล้ว
หลังจากลบ file นี้ไปรอบที่ 3
ผมก็คิดได้ว่า ถึงเวลาที่จะเริ่มทำความรู้จักกับเนื้อหาใน file นี้บ้างแล้ว
(ใช้คำว่าเริ่ม แสดงเจตจำนงว่าแค่เปิดพอให้รู้ว่ามันคืออะไร
ไม่ต้องการจะอ่านคู่มือให้รู้ลึกแต่อย่างใด)

If you exit Vim and later start it again, you would normally lose a lot of
information. The viminfo file can be used to remember that information, which
enables you to continue where you left off.


เนื้อหาใน file viminfo แบ่งออกเป็น
  • Last Search Pattern
    มีแค่รายการเดียวเสมอ เก็บเฉพาะ search แบบที่ใช้ pattern
  • Search String History
  • Command Line History
  • Expressoin History
  • Input Line History
  • Registers
  • File marks
    ตรงนี้น่าสนใจ ตรงที่เราสามารถ jump ไปตาม file+position
    ที่เราเคย edit ได้
    โดย vim จะ assign register 0-9 ให้กับ file+position เหล่านี้
    0 -> file+position ล่าสุด
    เราสามารถใช้คำสั่ง vim -c "normal '0"
    เพื่อเปิด file และกระโดดไปตำแหน่งล่าสุดที่เคยเปิดได้
  • Jumplist
    เก็บไว้เยอะแยะไปหมด อืมม์เวลาใช้มันจะจำอะไรได้บ้างเนี่ย
  • History of marks within files
    เก็บทุกๆ file ที่เคย edit เลย
    อันที่ทำให้ช้า ก็น่าจะเป็นอันท้ายนี่แหล่ะ

Related link from Roti