>> class Integer
>> def fact
>> (2..self).inject(1) {|acc,v| acc * v}
>> end
>> end
=> nil
>> 7.fact
=> 5040
Grovvy
groovy:000> Integer.metaClass.fact = {
groovy:001> delegate == 1 ? 1 : delegate * (delegate-1).fact()
groovy:002> }
===> groovysh_evaluate$_run_closure1@89ff97
groovy:000> 7.fact()
===> 5040
Scala
scala> class IntExt(v:Int) {
| def fact() = {
| (2 to v).foldLeft(1) (_ * _)
| }
| }
defined class IntExt
scala> implicit def FactExt(v:Int) = new IntExt(v)
FactExt: (Int)IntExt
scala> 7 fact
res33: Int = 5040
เจ้า scala นี่แปลกตรงมันใช้หลักการ Implicit conversions
อย่างประโยค
7 fact
จริงๆคือ7.fact()
แต่ method fact มันไม่มีใน class Int
ดังนั้น compiler จะดูว่ามี Implicit conversions rule อะไรอยู่บ้าง
ในกรณีนี้ ก็คือจะแอบแปลงให้เป็นแบบนี้
(new IntExt(7)).fact()
2 comments:
ท่าพิสดารของ Scala นี่เพื่อจะได้ไม่ต้องไปคิดจะ emulate ความ dynamic ยังไงหรือเปล่าครับ? ใช้ครอบๆ แบบนี้จะตรงไปตรงมากว่าถ้ามองจาก compiler?
veer: น่าจะใช่นะ, อย่าง groovy เขากระโดดลงเรือ Meta Object Protocol เต็มตัว
แต่เจ้า scala แค่ hack นิดหน่อย ก็ได้ feature open class มา (แต่ได้มา feature เดียว)
Post a Comment