Traits vs. Aspects in Scala 103

Posted by Dean Wampler Sun, 28 Sep 2008 03:33:00 GMT

Scala traits provide a mixin composition mechanism that has been missing in Java. Roughly speaking, you can think of traits as analogous to Java interfaces, but with implementations.

Aspects, e.g., those written in AspectJ, are another mechanism for mixin composition in Java. How do aspects and traits compare?

Let’s look at an example trait first, then re-implement the same behavior using an AspectJ aspect, and finally compare the two approaches.

Observing with Traits

In a previous post on Scala, I gave an example of the Observer Pattern implemented using a trait. Chris Shorrock and James Iry provided improved versions in the comments. I’ll use James’ example here.

To keep things as simple as possible, let’s observe a simple Counter, which increments an internal count variable by the number input to an add method.

    
package example

class Counter {
    var count = 0
    def add(i: Int) = count += i
}
    

The count field is actually public, but I will only write to it through add.

Here is James’ Subject trait that implements the Observer Pattern.

    
package example

trait Subject {
  type Observer = { def receiveUpdate(subject:Any) }

  private var observers = List[Observer]()
  def addObserver(observer:Observer) = observers ::= observer
  def notifyObservers = observers foreach (_.receiveUpdate(this))
}
    

Effectively, this says that we can use any object as an Observer as long as it matches the structural type { def receiveUpdate(subject:Any) }. Think of structural types as anonymous interfaces. Here, a valid observer is one that has a receiveUpdate method taking an argument of Any type.

The rest of the trait manages a list of observers and defines a notifyObservers method. The expression observers ::= observer uses the List :: (“cons”) operator to prepend an item to the list. (Note, I am using the default immutable List, so a new copy is created everytime.)

The notifyObservers method iterates through the observers, calling receiveUpdate on each one. The _ that gets replaced with each observer during the iteration.

Finally, here is a specs file that exercises the code.

    
package example

import org.specs._

object CounterObserverSpec extends Specification {
    "A Counter Observer" should {
        "observe counter increments" in {
            class CounterObserver {
                var updates = 0
                def receiveUpdate(subject:Any) = updates += 1
            }
            class WatchedCounter extends Counter with Subject {
                override def add(i: Int) = { 
                    super.add(i)
                    notifyObservers
                }
            }
            var watchedCounter = new WatchedCounter
            var counterObserver = new CounterObserver
            watchedCounter.addObserver(counterObserver)
            for (i <- 1 to 3) watchedCounter.add(i)
            counterObserver.updates must_== 3
            watchedCounter.count must_== 6
    }
  }
}
    

The specs library is a BDD tool inspired by rspec in Rubyland.

I won’t discuss it all the specs-specific details here, but hopefully you’ll get the general idea of what it’s doing.

Inside the "observe counter increments" in {...}, I start by declaring two classes, CounterObserver and WatchedCounter. CounterObserver satisfies our required structural type, i.e., it provides a receiveUpdate method.

WatchedCounter subclasses Counter and mixes in the Subject trait. It overrides the add method, where it calls Counter’s add first, then notifies the observers. No parentheses are used in the invocation of notifyObservers because the method was not defined to take any!

Next, I create an instance of each class, add the observer to the WatchedCounter, and make 3 calls to watchedCounter.add.

Finally, I use the “actual must_== expected” idiom to test the results. The observer should have seen 3 updates, while the counter should have a total of 6.

The following simple bash shell script will build and run the code.

    
SCALA_HOME=...
SCALA_SPECS_HOME=...
CP=$SCALA_HOME/lib/scala-library.jar:$SCALA_SPECS_HOME/specs-1.3.1.jar:bin
rm -rf bin
mkdir -p bin
scalac -d bin -cp $CP src/example/*.scala
scala -cp $CP example/CounterObserverSpec
    

Note that I put all the sources in a src/example directory. Also, I’m using v1.3.1 of specs, as well as v2.7.1 of Scala. You should get the following output.

    
Specification "CounterObserverSpec" 
  A Counter Observer should
  + observe counter increments

Total for specification "CounterObserverSpec":
Finished in 0 second, 60 ms
1 example, 2 assertions, 0 failure, 0 error
    

Observing with Aspects

Because Scala compiles to Java byte code, I can use AspectJ to advice Scala code! For this to work, you have to be aware of how Scala represents its concepts in byte code. For example, object declarations, e.g., object Foo {...} become static final classes. Also, method names like + become $plus in byte code.

However, most Scala type, method, and variable names can be used as is in AspectJ. This is true for my example.

Here is an aspect that observes calls to Counter.add.

    
package example

public aspect CounterObserver {
    after(Object counter, int value): 
        call(void *.add(int)) && target(counter) && args(value) {

        RecordedObservations.record("adding "+value);
    }
}
    

You can read this aspect as follows, after calling Counter.add (and keeping track of the Counter object that was called, and the value passed to the method), call the static method record on the RecordedObservations.

I’m using a separate Scala object RecordedObservations

    
package example

object RecordedObservations {
    private var messages = List[String]()
    def record(message: String):Unit = messages ::= message
    def count() = messages.length
    def reset():Unit = messages = Nil
}
    

Recall that this is effectively a static final Java class. I need this separate object, rather than keeping information in the aspect itself, because of the simple-minded way I’m building the code. ;) However, it’s generally a good idea with aspects to delegate most of the work to Java or Scala code anyway.

Now, the “spec” file is:

    
package example

import org.specs._

object CounterObserverSpec extends Specification {
    "A Counter Observer" should {
        "observe counter increments" in {
            RecordedObservations.reset()
            var counter = new Counter
            for (i <- 1 to 3) counter.add(i)
            RecordedObservations.count() must_== 3
            counter.count must_== 6
    }
  }
}
    

This time, I don’t need two more classes for the adding a mixin trait or defining an observer. Also, I call RecordedObservations.count to ensure it was called 3 times.

The build script is also slightly different to add the AspectJ compilation.

    
SCALA_HOME=...
SCALA_SPECS_HOME=...
ASPECTJ_HOME=...
CP=$SCALA_HOME/lib/scala-library.jar:$SCALA_SPECS_HOME/specs-1.3.1.jar:$ASPECTJ_HOME/lib/aspectjrt.jar:bin
rm -rf bin app.jar
mkdir -p bin
scalac -d bin -cp $CP src/example/*.scala 
ajc -1.5 -outjar app.jar -cp $CP -inpath bin src/example/CounterObserver.aj
aj -cp $ASPECTJ_HOME/lib/aspectjweaver.jar:app.jar:$CP example.CounterObserverSpec
    

The ajc command not only compiles the aspect, but it “weaves” into the compiled Scala classes in the bin directory. Actually, it only affects the Counter class. Then it writes all the woven and unmodified class files to app.jar, which is used to execute the test. Note that for production use, you might prefer load-time weaving.

The output is the same as before (except for the milliseconds), so I won’t show it here.

Comparing Traits with Aspects

So far, both approaches are equally viable. The traits approach obviously doesn’t require a separate language and corresponding tool set.

However, traits have one important limitation with respect to aspects. Aspects let you define pointcuts that are queries over all possible points where new behavior or modifications might be desired. These points are called join points in aspect terminology. The aspect I showed above has a simple pointcut that selects one join point, calls to the Counter.add method.

However, what if I wanted to observe all state changes in all classes in a package? Defining traits for each case would be tedious and error prone, since it would be easy to overlook some cases. With an aspect framework like AspectJ, I can implement observation at all the points I care about in a modular way.

Aspect frameworks support this by providing wildcard mechanisms. I won’t go into the details here, but the * in the previous aspect is an example, matching any type. Also, one of the most powerful techniques for writing robust aspects is to use pointcuts that reference only annotations, a form of abstraction. As a final example, if I add an annotation Adder to Counter.add,

    
package example

class Counter {
    var count = 0
    @Adder def add(i: Int) = count += i
}
    

Then I can rewrite the aspect as follows.

    
package example

public aspect CounterObserver {
    after(Object counter, int value): 
        call(@Adder void *.*(int)) && target(counter) && args(value) {

        RecordedObservations.record("adding "+value);
    }
}
    

Now, there are no type and method names in the pointcut. Any instance method on any visible type that takes one int (or Scala Int) argument and is annotated with Adder will get matched.

Note: Scala requires that you create any custom annotations as normal Java annotations. Also, if you intend to use them with Aspects, use runtime retention policy, which will be necessary if you use load-time weaving.

Conclusion

If you need to mix in behavior in a specific, relatively-localized set of classes, Scala traits are probably all you need and you don’t need another language. If you need more “pervasive” modifications (e.g., tracing, policy enforcement, security), consider using aspects.

Acknowledgements

Thanks to Ramnivas Laddad, whose forthcoming 2nd Edition of AspectJ in Action got me thinking about this topic.

Comments

Leave a response

  1. Avatar
    michi about 17 hours later:

    Nice to see some mention of Scala’s mixing composition and comparison to AOP. There is also a short discussion of this subject towards the end of http://lamp.epfl.ch/~odersky/papers/ScalableComponent.pdf

  2. Avatar
    Rafael de F. Ferreira 7 days later:

    I’m enjoying the posts about Scala, they seam to capture the main features that attracted me to the language.

    As I see it, in regarding to interception, AOP is too powerful (and complex) and trait mixins aren’t powerful enough. I think something like Beta’s notion of having methods derive from other methods would be a promising middle-of-the-road solution for the problem of interception. Actually in Beta there aren’t methods, everything is a “pattern” or something, but that is beside the point.

  3. Avatar
    annie2278 about 1 year later:

    To keep things as simple as possible, let’s observe a simple Counter, which increments an internal count variable by the number input to an add method.

  4. Avatar
    disney restaurants about 1 year later:

    With an aspect framework like AspectJ, I also want to implement observation at all the points I care about in a modular way. I’ll surly use runtime retention policy, which will be necessary for load-time weaving.

  5. Avatar
    MTS File Converter about 1 year later:

    I also want to implement observation at all the points I care about in a modular way.

  6. Avatar
    Software Reviews about 1 year later:

    I can only personally comment on this blog here. And like many have commented here, it’s very similar to some parts of US. Resources like the one you mentioned here will be very useful to me! I will post a link to this page on my blog. I am sure my visitors will find that very useful. I am always seeking online for articles that can help me

  7. Avatar
    cam about 1 year later:

    WatchedCounter subclasses Counter and mixes in the Subject trait. It overrides the add method, where it calls Counter’s add first, then notifies the observers.

  8. Avatar
    jewellery about 1 year later:

    ah ha you can have a yrt

  9. Avatar
    MLB baseball Jerseys about 1 year later:

    good posing

  10. Avatar
    saints jerseys about 1 year later:

    i want you can proving it day by day

  11. Avatar
    saints jersey about 1 year later:

    do you want to make more and more friends??

  12. Avatar
    cosplay about 1 year later:

    WatchedCounter subclasses Counter and mixes in the Subject trait. It overrides the add method, where it calls Counter’s add first, then notifies the observers.

  13. Avatar
    cheap vps about 1 year later:

    However, what if I wanted to observe all state changes in all classes in a package? Defining traits for each case would be tedious and error prone, since it would be easy to overlook some cases. With an aspect framework like AspectJ, I can implement observation at all the points I care about in a modular way. cheap VPS Aspect frameworks support this by providing wildcard mechanisms. I won’t go into the details here, but the * in the previous aspect is an example, matching any type. Also, one of the most powerful techniques for writing robust aspects is to use pointcuts that reference only annotations, a form of abstraction. As a final example, if I add an annotation Adder to Counter.add,

  14. Avatar
    Chantel Buchbinder about 1 year later:

    I like the style of your website, it is beautiful, people feel very free

  15. Avatar
    Shyla Droegmiller about 1 year later:

    I am accomplishing analysis plan in the acreage of solar energy. I charge digital abstracts of all-around solar radiation of Nepal. If accessible amuse accommodate us for added analysis or informations.

  16. Avatar
    Hunter Nuhfer about 1 year later:

    Hee i just want to give u a big thank you for your fantastic railscast! I’m looking forward to the next episodes!

  17. Avatar
    high top shoes about 1 year later:

    I am posting here just to let you know that you are doing a good job by keeping us posted about this. Please keep on posting such quality articles as this is a rare thing to find these days. I am always searching online for articles that can help me. Looking forward to another great blog. Good luck to the author! all the best!

  18. Avatar
    Rangemaster 110 over 2 years later:

    this is a great tutorial, really

  19. Avatar
    Regim Hotelier Bucuresti over 2 years later:

    The comparison is pretty relevant, as Scala’s interesting semantics for super calls in a class that mixes in multiple traits make them a good, type-safe alternative to AOP in a lot of cases.

    Unfortunately, apart from bare metal Java reflection, Scala lacks delegate support, so this means that your “advice” traits must share an “interface” with your “advised” implementations—it’s not as easy to reuse the same behaviour in multiple unrelated components the way you can with aspects.

    Let’s say you want to wrap a logging aspect around your components, but you want to centralize the logging logic.

  20. Avatar
    The North Face Shop over 2 years later:

    Buy the cheap North Face online in The North Face Shop for free shopping and save 50~70% OFF. north face outlet , Northface shop.

  21. Avatar
    chanel store over 2 years later:

    Here is very different. Thank you

  22. Avatar
    DRM Removal software over 2 years later:

    How they work. could you explain more clearly.

  23. Avatar
    gucci over 2 years later:

    I love your content & the way that you write.

  24. Avatar
    Pandora over 2 years later:

    you can think of traits as analogous to Java interfaces, but with implementations.

  25. Avatar
    pandora uk over 2 years later:

    I won’t discuss it all the specs-specific details here, but hopefully you’ll get the general idea of what it’s doing.

  26. Avatar
    iPhone SMS Transfer over 2 years later:

    We, how can we to be a good programmer, we should study alll the time, never lose our heart, keep good habit, learn from other people. that’s it.

  27. Avatar
    DVDtoiPad over 2 years later:

    you know, this is good, make sense, make it easy to understand.

  28. Avatar
    pandora over 2 years later:

    Had a good response nearly completed, ended up being evidence studying that & acquired erased by an advertisement for Shipwreck beads. Been age ranges since i have checked throughout the following & left since the big site modifications lsat summer season built participating by means of dial-up AGONIZING. I notice everything is very similar. Sleepless & sprang around from the Etsy boards which usually don’t pick up myself tonight… Spend a while stalking about the community forums & perusing products for sale & lately offered.

  29. Avatar
    Coach Factory Outlet over 2 years later:

    very similar. Sleepless & sprang around from the Etsy boards which usually don’t pick up myself tonight… Spend a while stalking about the community forums & perusing products for sale & lately offered.

  30. Avatar
    http://www.blacktowhiteiphone4.com over 2 years later:

    White iphone 4 Conversion Kit is now the hottest iphone 4 piece that you should get!

  31. Avatar
    Alix over 2 years later:

    What an amazing content is this and surely it makes realize each and everyone who read this. Thanks for providing so fantastic and sweet suggestions ….i really appreciate it. testking 70-647|testking 642-873|testking 70-643|testking 70-648|testking 646-985|testking JN0-304

  32. Avatar
    http://www.blacktowhiteiphone4.com over 2 years later:

    A few weeks ago when Steve Jobs held an extra press conference regarding the antenna problems with the white iPhone 4, Apple published a lot of information and a few videos that showed a similar problem with it’s competitors phones.

  33. Avatar
    Silicone Molding over 2 years later:

    Mold making is the core business of Intertech (Taiwan). With world level technology, Intertech enjoys a very good reputation for making Injection Mold and Plastic Moldsfor their worldwide customers.

  34. Avatar
    High Protein Foods over 2 years later:

    like the one you mentioned here will be very useful to me! I will post a link to this page on my blog. I am sure my visitors will find that very useful.

  35. Avatar
    outsource over 2 years later:

    Outsource services and solutions from oneoutsource. It provides best outsourcing services in india .

  36. Avatar
    monita over 2 years later:

    Things a lot of change right now in the education world. You don’t have to think twice if you want to continue your education. There are a lot of scholarships that you can get if yoy study hard in your high school. lottery numbers

  37. Avatar
    Criminal Check over 2 years later:

    Scala requires that you create any custom annotations as normal Java annotations.

  38. Avatar
    iPad ePub Transfer for Mac over 2 years later:

    I really like this essay. Thank you for writing it so seriously. I want to recommend it for my friends strongly. An Professional transfer that can transfer the ePub books onto your iPad on Mac and export the iPad ePub to Mac local folder.

  39. Avatar
    Cazare Ieftina Bucuresti over 2 years later:

    If you need to mix in behavior in a specific, relatively-localized set of classes, Scala traits are probably all you need and you don’t need another language.

  40. Avatar
    Criminal Records over 2 years later:

    Finally, I use the “actual must_== expected” idiom to test the results. The observer should have seen 3 updates, while the counter should have a total of 6.

  41. Avatar
    Criminal Search over 2 years later:

    Scala requires that you create any custom annotations as normal Java annotations. Also, if you intend to use them with Aspects, use runtime retention policy, which will be necessary if you use load-time weaving.

  42. Avatar
    Matteo over 2 years later:

    7

  43. Avatar
    mosic over 2 years later:

    8

  44. Avatar
    Jones over 2 years later:

    9

  45. Avatar
    iPad Video Converter for Mac over 2 years later:

    Thanks for your post, very informative.

  46. Avatar
    dswehfhh over 2 years later:

    We are the professional coats manufacturer, coats supplier, coats factory, custom coats.

  47. Avatar
    Designer Sunglasses over 2 years later:

    Buy $10 Replica Designer Sunglasses with 3-day FREE SHIPPING

  48. Avatar
    Pandora UK over 2 years later:

    Pandora UK jewellery sale online, cheaper than pandora chamilia and trollbeads

  49. Avatar
    dory over 3 years later:

    This is a good post. Thank you so much. Keep up the good works. Social Network

  50. Avatar
    Seobaglyak over 3 years later:

    Outsource services and solutions from oneoutsource. It provides best outsourcing services in india

  51. Avatar
    okey oyunu oyna over 3 years later:

    i will try it. Thanks

    internette görüntülü olarak okey oyunu oyna, gerçek kisilerle tanis, turnuva heyecanini yasa.

  52. Avatar
    ford leveling kit over 3 years later:

    Your article is so informative and I like it Thanks :-)

  53. Avatar
    leveling kit ford over 3 years later:

    Your article is so informative and I like it Thanks :-)

  54. Avatar
    leveling kit f250 over 3 years later:

    Your article is so informative and I like it Thanks :-)

  55. Avatar
    f350 leveling kit over 3 years later:

    Your article is so informative and I like it Thanks :-)

  56. Avatar
    Monster Beats By Dr. Dre Studio over 3 years later:

    The Monster Beats By Dr. Dre Studio Headphones are classic shoes.You will be proud of owning them. Don’t hesitate!Take Monster Beats By Dr. Dre Pro home! Choose our Monster Beats By Dr. Dre Solo Headphones will make you have an amazing discovery.

  57. Avatar
    christian louboutin shoes on sale over 3 years later:

    Have the christian louboutin patent leather pumps is a happy thing. Here have the most complete kinds of christian louboutin leather platform pumps.

  58. Avatar
    Jewellery over 3 years later:

    Online UK costume and fashion jewellery shop with,

    Online UK costume and fashion jewellery shop with,

    Online UK costume and fashion jewellery shop with,

    Online UK costume and fashion jewellery shop with,

  59. Avatar
    commission predators over 3 years later:

    It’s amazing how interesting it is for me to visit you very often.

  60. Avatar
    cookies gift baskets over 3 years later:

    it needs a bokmark so i can come back to it later ,nice stuff

  61. Avatar
    http://www.coachoutletstore-onlines.com over 3 years later:

    only do what you want to do

  62. Avatar
    hancy over 3 years later:

    It’s a lucky day!I get one pair of women heels from http://www.aliexpress.com/fm-store/908014 ! It’s have beautiful appearance and very comfortable! Here’s your first look at the first Women’s Heels that I have ever seen. I do believe this is the first time our store has released a Women’s Heels in a high top form.

  63. Avatar
    Bowtrol over 3 years later:

    Blog posts about wedding and bridal are always rare to find , at least with great quality,you qualify for a great blog post writer title,kep the great job happening

  64. Avatar
    Crystal Jewellery over 3 years later:

    Great post! Nice and informative, I really enjoyed reading it and will certainly share this post with my friends . Read everything you ever wanted to know about how to buy gold jewelry

  65. Avatar
    beats by dre store over 3 years later:

    e, I really enjoyed reading it and will certainly share this post with beats by dre sale cheap beats by dre

  66. Avatar
    beats by dre store over 3 years later:

    I really enjoyed reading it and will certainly share this post with my friends beats by dre sale cheap beats by dre

  67. Avatar
    Puma espera shoes over 3 years later:

    Both styles were seen in the World Cup worn by Eusebio da Silva Ferreira and in the Olympics worn by Lee Evans and Thomas Smith. Rudolf passed in 1974 of lung cancer, and his son ran the company. In 1989, Armin and Gerd Dassler sold Puma to Cosa Liebermann for a unknown amount. Since Puma was seen on the soccer field many years ago it’s still very popular with the players and fans. Puma offers tons of styles to pick from and with the basic look they never go out of style. Puma will be around for a very very long time.

  68. Avatar
    canada goose coat over 3 years later:

    When it comes to feather dress, what appears in your mind? Which kind brand of down jacket do you like prefer? Though there are many down jackets for you to choose from, on the word, which one you really enjoy? I want to say that canada goose coats is really your best choice. I believe you can’t agree with me any more. When you take the quality into consideration, you will find that it is superior to any other kind of coat. Besides, discount canada goose jackets is a world well-known brand, which has gained high reputation in the world, which has accepted by our customers and some organization. Because of its high quality, some of our loyal customers have promoted it to the people around them. In their opinion, it is good to informing others to know it. Recently, Canada Goose Trillium Parka is on hot sale. What I have to inform you is that all the products there are made by hand, so they are elaborative and elegant enough. It is really beautiful once you dress in. So, if you are a lovely girl or woman, go to the store to buy one for you. You will appreciate it that you have such a coat.In addition, they also have any other products like canada goose Gloves and canada goose jacket supplier.Hope your will like its!

  69. Avatar
    Ashley Bowling over 3 years later:

    “When the stars begin to huddle, the earth will soon become a puddle.”

  70. Avatar
    Fake Oakley Gascan sunglasses over 3 years later:

    http://www.oakleyshadestore.com/fake-oakley-gascan-c-29.html

  71. Avatar
    canada goose jakke over 3 years later:

    Berlusconi canada goose jakke sagde ved en nyheder canada goose konference i et par dage siden, Gruppen canada goose outlet af otte topmødet udvides gradvist i de belstaff outlet næste to dage.Alt mere end mere end 30 andre belstaff ledere af nationale og internationale organisationer Canada Goose Chilliwack Parka blev opfordret til forskellige temaer afholdt dialog med lederne af gruppen af otte, involverer Canada Goose Trillium Parka spørgsmål spænder fra globale økonomiske styring, klimaændringer, handel, udvikling og fødevarer Canada Goose Solaris Parka sikkerhed i Afrika.Berlusconi sagde, l ’ Aquila topmødet forventes i år at opnå væsentlige resultater Canada Goose Handsker på en række spørgsmål.

  72. Avatar
    christian louboutin over 3 years later:

    Blog posts about wedding and bridal are always rare to find , at least with great quality,you qualify for a great blog post writer title,kep the great job happening

  73. Avatar
    mr school over 3 years later:

    fuck girl vietnam please visit http://www.xxxgirl.us/2011/11/hoang-thuy-linh-paris-hilton-style-sex.html

  74. Avatar
    Cheap Beats By Dr.Dre over 3 years later:

    And M550i HR tend to music taste and string very good vocal performance voices sweet thick with deep feeling singing nuanced string flavour seemed to be able to smell the violin string the flickering light of loose filled with each frequency band appeal fragrance extension is very good density are first-class More information in the best sound headphones’s official

  75. Avatar
    cheap gucci over 3 years later:

    art jordan 6 rate, breathing air jordan 2011 , but still in a deep coma jordan release dates 2011 . It is reported that these jordan 3 10 days air jordan 5 and more time,...

  76. Avatar
    tv guide over 3 years later:

    great stuff. thanks a lot!

  77. Avatar
    grad school personal statement over 3 years later:

    Great blog. All posts have something to learn. Your work is very good and i appreciate you and hoping for some more informative posts. thank you……..

  78. Avatar
    backup iphone sms over 3 years later:

    Take effect to save the file and you can retrieve them when necessary.

  79. Avatar
    michael kors over 3 years later:

    I appreciate this post.Thanks

  80. Avatar
    iPhone contacts backup over 3 years later:

    I prefer Traits to Aspects. It is a good idea to make a right choice. so, make difference and it works for programming.

  81. Avatar
    Sarkari Naukri over 3 years later:

    I like the style of your website, it is beautiful, people feel very free

  82. Avatar
    Government jobs over 3 years later:

    Take effect to save the file and you can retrieve them when necessary.

  83. Avatar
    Bank jobs over 3 years later:

    I appreciate this post.Thanks

  84. Avatar
    Classifieds over 3 years later:

    I really enjoyed reading it and will certainly share this post with my friends

  85. Avatar
    Vivienne Westwood Jewellery over 3 years later:

    I will be asked to do everything the best I think! Can read your blog with my own than I found too much difference! I admire you!

  86. Avatar
    liudayun over 3 years later:

    I love this article, it’s very well.replica Oakley Commit SQ Sunglasses

  87. Avatar
    youngbrown over 3 years later:

    Thanks for the information, I’ll visit the site again to get update information video games

  88. Avatar
    bladeless fans over 4 years later:

    Traits vs. Aspects in Scala 87 good post53

  89. Avatar
    louboutin sales over 4 years later:

    Traits vs. Aspects in Scala 88 hoo,good article!!I like the post!88

  90. Avatar
    fdsfdsfds over 4 years later:

    This is a great post! Thanks.mac cosmetics saleOakley Sideways SunglassesOakley Bottlecap SunglassMAC Sheertone Blush saleReplica Oakley Commit SQ SunglassesMAC BrushOakley Commit SQ SunglassMAC Studio Finish Concealer sale

  91. Avatar
    Injection Mold over 4 years later:

    Intertech Machinery Inc. provides the most precise Plastic Injection Mold and Rubber Molds from Taiwan. With applying excellent unscrewing device in molds,

    Intertech is also very professional for making flip top Cap Molds in the world. Mold making is the core business of Intertech (Taiwan). With world level technology, Intertech enjoys a very good reputation for making Injection Mold and Plastic Molds for their worldwide customers.

  92. Avatar
    www.justbeenpaidfraud.com over 4 years later:

    Hi, I really liked this ruby on rails example. You can’t find these things anymore. I liked it. Great job.

  93. Avatar
    Cap Mold (100% made in Taiwan) over 4 years later:

    With more than 20 years of experience, Intertech provides an extensive integrated operational ability from design to production of molds 100% made in Taiwan. Additional to our own mold making factory, we also cooperate with our team vendors to form a very strong working force in Taiwan.

    For the overseas market, we work very closely with local representatives in order to take care of the technical communication and after-sales service to our customers. We also participate in the EUROMOLD & FAKUMA exhibitions and meet our customers every year in Europe. By concentrating on mold “niche markets”, we play a very useful mold maker role from the Far East whenever customers want to develop their new projects. We provide services from A to Z to our customers on a very economic cost and effect basis.

  94. Avatar
    gold hermes belt over 4 years later:

    Laptops are increasingly becoming a must have in the world of today?

  95. Avatar
    abercrombie over 4 years later:

    Il était certainement intéressant pour moi de lire le blog. Merci pour elle. J’aime ces sujets et tout connecté à eux. Je voudrais en savoir plus bientôt.

  96. Avatar
    printable coupon for hobby lobby over 4 years later:

    nice, gonna bookmark it love it all the way so far

  97. Avatar
    raihan over 4 years later:

    There was a great stuff in this article I really liked it very much! Gold had save a lots of informative site. Thanks a lot for this post!

  98. Avatar
    tita over 4 years later:

    I am very happy for visiting the nice info in this blog that to utilize the great technology in this blog. I am searching for some info that to using the great services in this website.

  99. Avatar
    surya over 4 years later:

    I wanted to thank for this great read!I really enjoyed reading. One of the more impressive blogs Ive seen. Thanks so much

  100. Avatar
    http://www.christianlouboutinonlineboutique.com/ over 4 years later:

    Espadrilles have become very popular with fashion lovers across the world. Christian Louboutin box Traditionally these shoes were made with natural material like cotton and christian louboutin ankle boot jute and were worn by farmers in Spain. They gradually became very popular Christian Louboutin men across the world because of the fact that they are very comfortable and men christian louboutin light-weight. Today, espadrilles shoes are available in all designs and wedge espadrilles are one of the most popular varieties.

  101. Avatar
    insan over 4 years later:

    Your article is so informative and I like it Thanks :-)

  102. Avatar
    dani over 4 years later:

    some truly cool information on this site , also I think the layout contains great features. very altruistic and nice :)

  103. Avatar
    plastic injection mold over 4 years later:

    Intertech Machinery Inc.

    With more than 25 years of experience, Intertech provides an extensive integrated operational ability from design to production of molds 100% made in Taiwan. Additional to our own mold making factory, we also cooperate with our team vendors to form a very strong working force in Taiwan.

    Main Products:

    Injection Mold, Silicone Molding, Rubber Mold, Silicone molding, PC High-Gloss Plastic Mold, Die Casting Mold, Silicone Mold, Silicone Rubber Mold, Liquid Silicone Rubber , Cosmetic Packaging Mold, Medical Products Mold, Engineering Plastic Molds, Home Appliances Mold, etc…

Comments