Successfully reported this slideshow.

More Related Content

Related Books

Free with a 14 day trial from Scribd

See all

Related Audiobooks

Free with a 14 day trial from Scribd

See all

From dot net_to_rails

  1. 1. From .NET to Rails, A Developers Story<br />Today’s Sponsors<br />
  2. 2. Who the f**k is Colin Gemmell<br />.NET Dev for 3.5 years<br />Webforms, Umbraco, MVC<br />Big on ALT.NET ideals<br />Moved to Ruby on Rails in May 2010<br />
  3. 3. Why Ruby and Rails<br />Cheaper than developing with .NET<br />Arguably faster and more productive<br />Easier to test your code<br />Open and free development<br />
  4. 4. Why Ruby and Rails<br />This man pays me to.<br />@chrisvmcd<br />
  5. 5. .NET Development Environment<br />Window XP/Vista/7<br />Visual Studio 20XX<br />Resharper or Code Rush<br />
  6. 6. My First Ruby Development Environment<br />Window XP/Vista/7<br />Rubymine<br />Cygwin<br />Ruby Gems<br />Interactive Ruby Console (irb)<br />
  7. 7. Windows Problems<br />Rails traditionally deployed on Linux OS<br />Gem’s often use Linux kernal methods<br />or Linux Libraries<br />Engineyard investing on Rails development with windows<br />
  8. 8. Development Environment<br />VMware workstation<br />Ubuntu<br />Rubymine<br />VIM + a lot of plugins<br />Ruby Gems<br />Interactive Ruby Console (irb)<br />
  9. 9. Development Environment<br />Find what is right for you.<br />
  10. 10. Ruby<br />Ruby Koans (http://rubykoans.com/)<br />
  11. 11. Ruby and SOLID<br />Single responsibility<br />Open/Closed <br />Liskov Substitution <br />Interface Segregation <br />Dependency Injection<br />
  12. 12. Ruby and loose coupling<br />In .NET we use Interface and Dependency Injection to achieve loose coupling<br />Ruby is loosely coupled by design.<br />Everything and anything can be changed.<br />Thanks to being a dynamic language and…… <br />
  13. 13. Ruby and Monkey Patching<br />
  14. 14. Add New Functionality to Ruby<br />"Developer DeveloperDeveloper is awesome".second_word<br />NoMethodError: undefined method `second_word' for "developer developerdeveloper":String<br />classString<br />defsecond_work<br />returnself.split(' ')[1]<br />end<br />end<br />"Developer DeveloperDeveloper is awesome".second_word<br />=== “Developer”<br />Extension methods anyone?<br />
  15. 15. Changing implementation<br />classZombieKiller<br /> defkill<br />self.shotgun.fire<br />end<br />end<br />zombie_killer=ZombieKiller.new<br />puts(zombie_killer.kill)<br />===Zombieheadexplodes<br />classZombieKiller<br />defkill<br />self.axe.throw<br />end<br />end<br />zombie_killer=ZombieKiller.new<br />puts(zombie_killer.kill)<br />===ZombieFalls off<br />
  16. 16. Are you scared yet?<br />If the idea of monkey patching scares you a little, it probably should. Can you imagine debugging code where the String class had subtly different behaviours from the String you've learned to use? Monkey patching can be incredibly dangerous in the wrong hands.<br />Jeff Atwood<br />http://www.codinghorror.com/blog/2008/07/monkeypatching-for-humans.html<br />
  17. 17. Testing Ruby and Rails<br />
  18. 18. Testing Ruby and Rails<br />Testing ensures code behaves correctly<br />Tests ensure code compiles<br />Debugging support patchy at best<br />Its all right, testing is a lot simpler<br />
  19. 19. How I Tested .NET<br />[TestFixture]<br />publicclassZombieKillerTest:SpecificationBase{<br />privateZombieKillerzombieKiller;<br />privateZombiezombie;<br />publicoverridevoidGiven(){<br />varrepo=Mock<IZombieKillerRepository>()<br />zombie=newZombie(Strength.Week,Speed.Fast)<br />zombieKiller=newZombieKiller(repo)<br />repo.stub(x=>x.UpdateZombie).returns(true)<br />zombieKiller.weapon=Weapon.Axe<br />}<br />publicoverridevoidWhen(){<br />zombieKiller.kill(zombie)<br />}<br />[Test]<br />publicvoidshould_depacite_zombie(){<br />zombie.status.should_eqaul("decapitated")<br />}<br />}<br />publicclassZombieKiller:IZombieKiller{<br />privateIZombieKillerRepository_repo;<br />publicZombieKiller(<br />IZombieKillerRepositoryrepo){<br />_repo=repo<br />}<br />publicvoidKill(Zombiezombie){<br />zombie.status="decapitated"<br />repo.UpdateZombie(zombie)<br />}<br />}<br />
  20. 20. Example RSpec test<br />classZombieKiller<br />defkillzombie<br />zombie.attack_withself.weapon<br />end<br />End<br />classZombie<ActiveRecord::Base<br />defattack_withweapon<br />#do some logic to see <br /> #what happened to zombie<br />self.save<br /> end<br />end<br />describe"when killing a zombie"do<br />classZombie<br />defsave<br />true<br />end<br />end<br />beforedo<br />@zombie=Zombie.new(<br />:strength=>:week,:speed=>:fast)<br />@zombie_killer=ZombieKiller.new(<br />:weapon=>:axe)<br />@zombie_killer.kill(@zombie)<br />end<br />it"should be decapitated if hit with axe"do<br />@zombie.status.shouldeql(:decapitated)<br />end<br />end<br />
  21. 21. Range of Testing<br />In .NET there are a lot of test frameworks<br />Ruby test frameworks include TestUnit, RSpec, Shoulda and Cucumber<br />Rails encourages testing at all levels.<br />All extremely well documented.<br />
  22. 22. The Rails Way<br />One project layout and only one layout<br />Principle of least surprise<br />Change it at your own risk<br />Heavily based on conventions e.g.<br />ZombieController > ZombieControllerSpec Zombie > ZombieSpec (or ZombieTest)<br /> Zombie > ZombieController<br />This can be applied to .NET too<br />
  23. 23. Makes really fast to get going with project<br />The number one reason for slow apps (IMHO)<br />Is to easy to write code that over uses the database<br />Often don’t/forget to think about DB<br />The Curse of Active Record<br />
  24. 24. The Curse of Active Record<br />1 classSession<ActiveRecord::Base<br />2 # name > string<br />3 # code > string<br />4 <br />5 validates_uniqueness_of:name,:code<br />6 includeSessionModel<br />7<br />8 defgenerate_code<br />9 returnif!(self.code.nil?||self.code.empty?)<br />10 full_code=""<br />11 while(true)<br />12 code="%04d"%rand(9999)<br />13 full_code=“ABC#{code}"<br />14 breakifSession.code_is_unique?(full_code)<br />15 end<br />16 self.code=full_code<br />17 end<br />18 end<br />19 moduleSessionModel<br />20 defself.includedklass<br />21 klass.extendClassMethods<br />22 end<br />23<br />24 moduleClassMethods<br />25 defcode_is_unique?(code)<br />26 returnself.find_by_code(code).nil?<br />27 end<br />28 end<br />29 end<br />Spot the database calls...<br />
  25. 25. The Curse of Active Record<br />classSession<ActiveRecord::Base<br /># name > string<br /># code > string <br />validates_uniqueness_of:name,:code x 2<br />includeSessionModel<br />defgenerate_code<br />returnif!(self.code.nil?||self.code.empty?)<br />full_code=""<br />while(true)<br />code="%04d"%rand(9999)<br />full_code=“ABC#{code}"<br />breakifSession.code_is_unique?(full_code)<br />end<br />self.code=full_code<br />end<br />end<br />moduleSessionModel<br />defself.includedklass<br />klass.extendClassMethods<br />end<br />moduleClassMethods<br />defcode_is_unique?(code)<br />returnself.find_by_code(code).nil?<br />end<br />end<br />end<br />This was production code. The names have been changed to protect the innocent <br />
  26. 26. .NET deployment predominantly through FTP or copy to file share<br />But what about databases, migrations, queues, externals dependencies etc.<br />Fear common place on deployment day<br />.NET Deployment<br />
  27. 27. Deployment is a solved problem in Rails<br />Built on several parts<br />Database migration come out of the box<br />Bundler gets dependency<br />Use of Chef or Capistrano for externals or configuration changes<br />Platform as a service combine all of these e.g. Heroku, Engineyard, Brightbox<br />Ruby Deployment<br />
  28. 28. Deployment<br />Shock horror its a demo<br />
  29. 29. It’s the future<br />“Its the new hotness” – Rob Ashton<br />
  30. 30. From .NET to Rails, A Developers Story<br />Any Questions?<br />E-mail: pythonandchips@gmail.com<br />Blog: pythonandchips.net<br />Twitter: @colin_gemmell<br />Today’s Sponsors<br />

×