Showing posts with label import alias. Show all posts
Showing posts with label import alias. Show all posts

Thursday, January 21, 2010

Exclude style import semantics

I can't remember if I posted this tip yet so I will do it again (or not :-P ).

If you want to import all classes in a package or object exception for one or two there is a neat trick to exclude the unwanted elements:
  1. /*
  2. The File class is aliased to _ (oblivion) and then everything is imported (except File since it does not exist in that scope)
  3. Note: File can be imported later
  4. */
  5. scala> import java.io.{File=>_,_}
  6. import java.io.{File=>_, _}
  7. scala> new File("it is a file")      
  8. < console>:8: error: not found: type File
  9.        new File("it is a file")
  10. scala> object O {
  11.      | def one = 1
  12.      | def two = 2
  13.      | def o = 0
  14.      | }
  15. defined module O
  16. /*
  17. Same tricks can apply to importing methods and fields from objects
  18. */
  19. scala> import O.{o=>_, _}
  20. import O.{o=>_, _}
  21. scala> one
  22. res2: Int = 1
  23. scala> two
  24. res3: Int = 2
  25. scala> o
  26. < console>:15: error: not found: value o
  27.        o
  28. // Once a class is imported into scope it can not be removed
  29. scala> import java.io.File
  30. import java.io.File
  31. scala> import java.io.{File=>_}
  32. import java.io.{File=>_}
  33. /*
  34. this still works because the previous import statement only adds an alias it does not remove the alias
  35. */
  36. scala> new File("..")          
  37. res6: java.io.File = ..
  38. // There can be multiple aliases in a scope
  39. scala> import java.io.{File=>jfile}
  40. import java.io.{File=>jfile}
  41. scala> new jfile("..")
  42. res0: java.io.File = ..
  43. // one more example of importing from objects
  44. scala> case class X(a:Int, b:Int, c:Int)
  45. defined class X
  46. scala> val x = new X(1,2,3)
  47. x: X = X(1,2,3)
  48. scala> import x.{a=>_,b=>_,_}
  49. import x.{a=>_, b=>_, _}
  50. scala> c 
  51. res1: Int = 3
  52. scala> b
  53. < console>:14: error: not found: value b
  54.        b
  55.        ^

Wednesday, September 9, 2009

Using objects to access trait functionality

Today's topic is based on an article by Bill Venners. http://www.artima.com/scalazine/articles/selfless_trait_pattern.html. I recommend reading that article as it goes into much more detail. I also recommend taking a look at the earlier topic that covers companion objects.

The normal way to use a trait is to mix it in to an object. However there can be a problem mixing two traits containing methods with equal signatures. If the two traits are not designed to work together then you will get a compile error. Otherwise one method will override the other. Either way you cannot access both methods. There is an additional way to access the functionality of a trait. You can create an object (not instance) that extends the trait and import the methods when you need them.

If the trait is stateless then the object can be shared if not then make sure that sharing the object is carefully handled.

Examples:
  1. scala> trait T1 {
  2.      | def talk = "hi"
  3.      | }
  4. defined trait T1
  5. scala> trait T2 {
  6.      | def talk = "hello"
  7.      | }
  8. defined trait T2
  9. // Cannot extend C with T1 and T2 because they are not designed to work together
  10. scala> class C extends T1 with T2
  11. :6: error: error overriding method talk in trait T1 of type => java.lang.String;
  12.  method talk in trait T2 of type => java.lang.String needs override modifier
  13.        class C extends T1 with T2
  14.              ^
  15. scala> class C extends T1
  16. defined class C
  17. // objects can have state so becareful how you share them
  18. scala> object Obj1 extends T1
  19. defined module Obj1
  20. scala> object Obj2 extends T2
  21. defined module Obj2
  22. // You can give aliases to the imported methods and use them in the class
  23. scala> class C {
  24.      | import Obj1.{talk => hi}
  25.      | import Obj2.{talk => hello}
  26.      | def sayHi = hi
  27.      | def sayHello = hello
  28.      | }
  29. defined class C
  30. scala> val c = new C
  31. c: C = C@54d8fd1a
  32. scala> c.sayHi
  33. res0: java.lang.String = hi
  34. scala> c.sayHello
  35. res1: java.lang.String = hello
  36. scala> class C extends T1 {
  37.      | import Obj2.{talk => hello}
  38.      | def helloTalk = hello
  39.      | }
  40. defined class C
  41. scala> val c2 = new C
  42. c2: C = C@2ee634bf
  43. scala> c2.talk
  44. res2: java.lang.String = hi
  45. scala> c2.helloTalk
  46. res5: java.lang.String = hello
Subscribe to: Comments (Atom)

AltStyle によって変換されたページ (->オリジナル) /