Upgrade to Pro — share decks privately, control downloads, hide ads and more …

A Bemedianced™ Introduction to Ruby

A Bemedianced™ Introduction to Ruby

An introduction for beginner/intermediate/advanced Ruby developers

Avatar for Andrea Rossi

Andrea Rossi

November 08, 2017
Tweet

Other Decks in Programming

Transcript

  1. WHAT IS RUBY? (trademark pending) Ruby is a dynamic, reflective,

    object-oriented, general- purpose programming language. It was designed and developed in the mid-1990s by Yukihiro "Matz" Matsumoto in Japan. Bemedianced
  2. AN INTERPRETED LANGUAGE (trademark pending) • Ruby MRI (Matz's Ruby

    Interpreter) Bemedianced • JRuby • Rubinius
  3. AN INTERPRETED LANGUAGE (trademark pending) Bemedianced JRUBY require 'java' frame

    = javax.swing.JFrame.new("Window") # Creating a Java JFrame label = javax.swing.JLabel.new("Hello") # We can transparently call Java methods on Java objects, # just as if they were defined in Ruby. frame.add(label) # Invoking the Java method 'add'. frame.setDefaultCloseOperation(javax.swing.JFrame!::EXIT_ON_CLOSE) frame.pack frame.setVisible(true)
  4. AN INTERPRETED LANGUAGE (trademark pending) Bemedianced JRUBY require '!../my-jars/spatial4j.jar' wkt

    = 'POLYGON((0 0, 10 0, 10 20, 5 -5, 0 20, 0 0))' factory = JtsSpatialContextFactory.new factory.validationRule = ValidationRule.repair_buffer0 ctx = factory.new_spatial_context buffer0 = ctx.readShapeFromWkt(wkt) !!...
  5. (trademark pending) BOOLEAN irb(main):0> true !=> true irb(main):0> false !=>

    false irb(main):0> true !|| false !=> true irb(main):0> true !&& false !=> false irb(main):0> (true !|| true) !|| 1 !== 1 !=> true DATA TYPES Bemedianced
  6. (trademark pending) BOOLEAN irb(main):0> (something.present? !&& something.this) !|| "that" !=>

    "this" irb(main):0> (something.present? and something.this) or "that" !=> "this" DATA TYPES Bemedianced
  7. (trademark pending) STRING irb(main):0> 'this is a string' !=> 'this

    is a string' irb(main):0> "and so is this" !=> "and so is this" irb(main):0> a_var = 'interpolated' irb(main):0> "this string can be !#{a_var}" !=> "this string can be interpolated" irb(main):0> "a word".upcase !=> "A WORD" irb(main):0> "two" !<< " strings" # this is different !=> "two strings" irb(main):0> "two" + " strings" # from this !=> "two strings" DATA TYPES Bemedianced
  8. (trademark pending) DATA TYPES Bemedianced irb(main):0> A_CONSTANT = 'this should

    stay the same' !=> "this should stay the same" irb(main):0> A_CONSTANT !<< " but it doesn't!" !=> "this should stay the same but it doesn't!" irb(main):0> A_CONSTANT !=> "this should stay the same but it doesn't!" STRING
  9. (trademark pending) DATA TYPES Bemedianced irb(main):0> TRY_AGAIN = 'this should

    stay the same'.freeze !=> "this should stay the same" irb(main):0> TRY_AGAIN !<< " but it doesn't!".freeze RuntimeError: can't modify frozen String from (irb):84 irb(main):0> TRY_AGAIN !=> "this should stay the same" STRING
  10. (trademark pending) Benchmark.bm do |x| CONSTANT = "string".freeze var =

    'another_string' x.report('freeze') { 10_000_000.times { var !== CONSTANT } } x.report('no_freeze') { 10_000_000.times { var !== 'string' } } x.report('to_sym') { 10_000_000.times { var.to_sym !== :string } } end freeze 0.490000 0.000000 0.490000 ( 0.490177) no_freeze 1.130000 0.000000 1.130000 ( 1.151812) to_sym 1.220000 0.010000 1.230000 ( 1.229188) DATA TYPES Bemedianced STRING
  11. (trademark pending) SYMBOL DATA TYPES Bemedianced irb(main):0> :a_symbol !=> :a_symbol

    irb(main):0> :a_symbol.object_id # never changes !=> 773468 irb(main):0> :a_symbol !== :another_symbol # super fast !=> false
  12. (trademark pending) NUMBER DATA TYPES irb(main):0> 1 + 1 !=>

    2 irb(main):0> 0.1 + 0.2 !=> 0.30000000000000004 irb(main):0> _.round(1) !=> 0.3 irb(main):0> "I can interpolate !#{3 + 5}!" !=> "I can interpolate 8!" Bemedianced
  13. (trademark pending) ARRAY DATA TYPES irb(main):0> an_array = [1, 2,

    3, 4] !=> [1, 2, 3, 4] irb(main):0> an_array !<< 5 !=> [1, 2, 3, 4, 5] irb(main):0> an_array += [6, 7] !=> [1, 2, 3, 4, 5, 6, 7] irb(main):0> an_array.max !=> 7 Bemedianced
  14. (trademark pending) ARRAY DATA TYPES irb(main):0> an_array.class !=> Array irb(main):0>

    an_array.class.ancestors !=> [Array, Enumerable, Object, Kernel, BasicObject] irb(main):0> an_array.each { |num| # do something with num } !=> [1, 2, 3, 4, 5, 6, 7] irb(main):0> an_array.map { |num| num + 1 } !=> [2, 3, 4, 5, 6, 7, 8] irb(main):0> an_array.select { |num| num.odd? } !=> [1, 3, 5, 7] Bemedianced
  15. (trademark pending) ARRAY DATA TYPES irb(main):0> final = an_array.each_with_object("The numbers

    are") do |num, string| irb(main):1> string !<< " !#{num}" irb(main):2> end !=> "The numbers are 1 2 3 4 5 7 8" irb(main):0> final !=> "The numbers are 1 2 3 4 5 7 8" Bemedianced
  16. (trademark pending) ARRAY DATA TYPES irb(main):0> duplicates = [] !=>

    true irb(main):0> duplicates !<< 1 !=> [1] irb(main):0> duplicates !<< 1 !=> [1, 1] irb(main):0> duplicates !<< 2 !=> [1, 1, 2] irb(main):0> duplicates.uniq !=> [1, 2] Bemedianced
  17. (trademark pending) ARRAY DATA TYPES irb(main):0> require 'set' !=> true

    irb(main):0> set = Set.new !=> #<Set: {}> irb(main):0> set !<< 1 !=> #<Set: {1}> irb(main):0> set !<< 1 !=> #<Set: {1}> irb(main):0> set !<< 2 !=> #<Set: {1, 2}> irb(main):0> set.to_a !=> [1, 2] Bemedianced
  18. (trademark pending) HASH DATA TYPES Bemedianced irb(main):0> {"a string" !=>

    2} !=> {"a string" !=> 2} irb(main):0> {a_symbol: "a string"} !=> {:a_symbol !=> "a string"} irb(main):0> {a: 2, "b" !=> 2.4} !=> {:a !=> 2, "b" !=> 2.4} irb(main):0> {rand() !=> 24} # anything can be a hash key !=> {0.33565217456135554!=>24}
  19. (trademark pending) HASH DATA TYPES Bemedianced irb(main):0> a_hash = {a:

    2, b: 4} !=> {a: 2, b: 4} irb(main):0> a_hash[:a] !=> 2 irb(main):0> a_hash.merge({b: 6}) !=> {:a !=> 2, :b !=> 6} irb(main):0> a_hash !=> {:a !=> 2, :b !=> 4}
  20. (trademark pending) HASH DATA TYPES irb(main):0> a_hash[:a] = {inner: {super_inner:

    4}} !=> {:inner !=> {:super_inner !=> 4}} irb(main):0> a_hash[:a][:inner][:super_inner] !=> 4 irb(main):0> a_hash.dig(:a, :inner, :super_inner) !=> 4 irb(main):0> a_hash[:a] = nil !=> nil irb(main):0> a_hash.dig(:a, :inner, :super_inner) !=> nil Bemedianced Ruby 2.3
  21. (trademark pending) HASH DATA TYPES MODIFIERS = { String !=>

    lambda { |value| value + " (modified)" }, Integer !=> lambda { |value| value + 1 }, Float !=> lambda { |value| value + 0.1 } } ["this", 13, "that", 1.4].map do |value| MODIFIERS[value.class][value] end # ["this (modified)", 14, "that (modified)", 1.5] Bemedianced
  22. (trademark pending) HASH DATA TYPES MODIFIERS = { String !=>

    lambda { |value| value + " (modified)" }, Integer !=> lambda { |value| value + 1 }, Float !=> lambda { |value| value + 0.1 } } ["this", 13, "that", 1.4].map do |value| MODIFIERS[value.class][value] end # ["this (modified)", 14, "that (modified)", 1.5] Bemedianced
  23. OOP IN RUBY (trademark pending) Bemedianced CLASSES class Animal def

    initialize(species) @species = species end end
  24. OOP IN RUBY (trademark pending) Bemedianced CLASSES class Animal def

    initialize(species) @species = species end end a_doggo = Animal.new("doggo")
  25. OOP IN RUBY (trademark pending) Bemedianced CLASSES class Animal def

    initialize(species) @species = species end end a_doggo = Animal.new("doggo") a_doggo.species NoMethodError: undefined method `species' for #<Animal:0x007fc9580117f0 @species="doggo">
  26. OOP IN RUBY (trademark pending) Bemedianced CLASSES class Animal def

    initialize(species) @species = species end def species # a method! @species end end a_doggo = Animal.new("doggo") a_doggo.species !=> "doggo"
  27. OOP IN RUBY (trademark pending) Bemedianced CLASSES class Animal attr_reader

    :species def initialize(species) @species = species end end a_doggo = Animal.new("doggo") my_class_obj.species !=> "doggo"
  28. OOP IN RUBY (trademark pending) Bemedianced CLASSES class Animal def

    initialize(species) @species = species end def species=(species) @species = species end end catdog = Animal.new("cat") catdog = "dog" !=> "dog"
  29. OOP IN RUBY (trademark pending) Bemedianced CLASSES class Animal attr_writer

    :species def initialize(species) @species = species end end catdog = Animal.new("cat") catdog.species = "dog" !=> "dog"
  30. OOP IN RUBY (trademark pending) Bemedianced CLASSES class Animal attr_accessor

    :species def initialize(species) @species = species end end catdog = Animal.new("cat") catdog.species !=> "cat" catdog.species = "dog" !=> "dog"
  31. OOP IN RUBY (trademark pending) Bemedianced CLASSES class Doggo <

    Animal def initialize @species = "doggo" end end a_doggo = Doggo.new a_doggo.species !=> "doggo"
  32. OOP IN RUBY (trademark pending) Bemedianced CLASSES class Doggo <

    Animal def initialize @species = "doggo" end def walk "I'm walking here!" end end a_doggo = Doggo.new a_doggo.walk !=> "I'm walking here!"
  33. OOP IN RUBY (trademark pending) Bemedianced MODULES class Doggo <

    Animal include CanWalk end a_doggo = Doggo.new a_doggo.walk !=> "I'm walking here!"
  34. OOP IN RUBY (trademark pending) CLASSES Bemedianced class Configurator include

    Singleton attr_accessor :config def initialize @config = YAML.load("initial_config.yml").deep_symbolize_keys end class !<< self def get(key) instance.config[key] end def set(key, value) instance.config[key] = value end end end Configurator.get(:port) !=> 8000
  35. Bemedianced OOP IN RUBY CLASSES class User < ActiveRecord!::Base devise

    :token_authenticatable, :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :confirmable, :omniauthable include AccountValidation include HasProfiles include HasAvatar include EmailsRecipient include HasDevices include HasServers include HasPlaylists include HasEntitlements include HasFeatures include HasRoles !!...
  36. Bemedianced OOP IN RUBY CLASSES class Marketing!::User < DelegateClass(Core!::User) def

    receives_newsletter? created_at > DateTime.new(2010) end end class Billing!::User < DelegateClass(Core!::User) def restore_purchase PayPal.restore(id) end end user = Core!::User.where(username: "tommywiseau") billing_user = Billing!::User.new(user) billing_user.restore_purchase
  37. OOP IN RUBY (trademark pending) MODULES Bemedianced module Headers def

    self.parse(headers) # do stuff to parse the headers end def self.print(headers) print headers end end
  38. OOP IN RUBY (trademark pending) MODULES Bemedianced module Headers extend

    self def parse(headers) # do stuff to parse the headers end def print(headers) print headers end end
  39. Bemedianced OOP IN RUBY METAPROGRAMMING class RubyMeetup meetup_api = "https:!//api.meetup.com/rsvp/15123523"

    HTTParty.get(meetup_api)["results"].each do |result| define_method(result["member"]["name"].snakecase) do "!#{result["member"]["name"]} is here!" end end end RubyMeetup.new.andrea_rossi !=> "Andrea Rossi is here!"
  40. WEB DEVELOPMENT IN RUBY Bemedianced RUBY ON RAILS Strong conventions!

    Super-rapid development! Lots and lots of gems!
  41. WEB DEVELOPMENT IN RUBY Bemedianced RUBY ON RAILS Strong conventions!

    Super-rapid development! Lots and lots of gems! Overkill?
  42. WEB DEVELOPMENT IN RUBY Bemedianced RUBY ON RAILS Strong conventions!

    Super-rapid development! Lots and lots of gems! Overkill? It's not blazingly fast (sorry)
  43. WEB DEVELOPMENT IN RUBY SINATRA+GRAPE (can be) Blazingly fast Much

    less code involved Deeper understanding of the stack Bemedianced
  44. WEB DEVELOPMENT IN RUBY SINATRA+GRAPE (can be) Blazingly fast Much

    less code involved Deeper understanding of the stack A bit of boilerplate is required Bemedianced
  45. WEB DEVELOPMENT IN RUBY SINATRA+GRAPE (can be) Blazingly fast Much

    less code involved Deeper understanding of the stack A bit of boilerplate is required You make the conventions / Bemedianced
  46. WEB DEVELOPMENT IN RUBY HEXAGONAL RAILS/SINATRA/GRAPE Makes testing so much

    easier SEPARATE ALL THE CONCERNS Much lower maintenance costs Bemedianced
  47. WEB DEVELOPMENT IN RUBY HEXAGONAL RAILS/SINATRA/GRAPE Makes testing so much

    easier SEPARATE ALL THE CONCERNS Much lower maintenance costs Can get over-complicated if not planned Bemedianced
  48. WEB DEVELOPMENT IN RUBY HEXAGONAL RAILS/SINATRA/GRAPE Makes testing so much

    easier SEPARATE ALL THE CONCERNS Much lower maintenance costs Can get over-complicated if not planned Can be a hard sell to management Bemedianced