Ruby

Why It's Here and Where It's Going

Speaker notes added in italics

"Don't underestimate the human factor."

Ruby is from Japan. Ruby's creator, Yukihiro Matsumoto or "Matz", stresses that code should prioritize human needs, not computers' needs.

Ruby is an outlier if you consider language origin. Is it possible that its origin accounts for some of the things that make it special?

Try Ruby

Matz' focus on easily-accessible, human-friendly programming spilled into the Ruby community. tryruby.org is a great example of this. It pays homage to _why, an early Ruby personality.

Rails

DHH & Stuff

Ruby on Rails made Ruby famous. Rails was warmly received and remains loved for its dedication to making development fast & easy, for providing smart conventions and for enabling endless customization and specialization.

Ruby Today Now

These days, there are lots of ways to run Ruby code.

Why do we love it so?

"Principle of Least Surprise"

name = "Star Wars"
name << ": The Force Awakens"
# => "Star Wars: The Force Awakens"

crew =  ["Han Solo", "Chewbacca"] 
crew << "Luke Skywalker" << "Ben Kenobi"
# => ["Han Solo", "Chewbacca", "Luke Skywalker", "Ben Kenobi"]
(1..10) 
# => 1 .. 10
('a'..'z')
# => "a" .. "z"
started_at = Time.new("2011-01-01")
ended_at =   Time.new("2011-12-31")

the_year_2011 = (started_at..ended_at)
# => 2011-01-01 00:00:00 -0800..2011-01-01 00:00:00 -0800

In Ruby, all objects behave basically the same way. This means that once you learn a few Ruby APIs, you know what to expect from new ones. 

class Aquarium
  attr_accessor :fishes

  def initialize(fishes=[])
    self.fishes = fishes 
  end
  

















end

Build Your Dreams

# initialize with an array of fishes
tank = Aquarium.new(["Goldie", "Fishy"])

# add fishes
tank << "Comet"

# combine Aquariums
bowl = Aquarium.new(["Alpha"])
koi_pond = tank + bowl 

# find fishes by name
koi_pond["Goldie"]
  def +(other_aquarium) 
    # join fishes together
    new_fish = self.fishes +
      other_aquarium.fishes 
    Aquarium.new(new_fish)
  end
  def <<(fish) 
    # add a fish to the collection,
    # return self
    self.fishes << fish 
    self
  end

  def [](fish)
   # lookup a fish by name
   self.fishes.find { |f| f == fish }
  end

With Ruby, just imagine how your objects should behave. You can always implement it. Since operators are aliases for methods, your custom objects feel like built-ins.

Check Yourself

const_defined?(:Fish) # => true
fish_class = const_get(:Fish)
Fish.ancestors 
# => [Fish, Animal, Vertebrate, Object, 
#       Kernel, BasicObject]
Fish.method_defined?(:swim)
Fish.instance_method(:swim) # => BoundMethod
shiny = Fish.new(name: "Shiny")
shiny.class # => #<class: Fish>
shiny.instance_variable_get("@name")
# => "Shiny"
shiny.is_a?(Fish)   # => true
shiny.is_a?(Animal) # => true
shiny.respond_to?(:swim!) # => true 
shiny.respond_to?(:walk!) # => false 

Your app is made of values and code stored in the VM's memory. Ruby gives you lots of ways to inspect it.

Wreck Yourself

const_defined?(:Fish) # => true

class Fish 
  def saute 
    # add oil & heat
  end
end


COOKING_METHODS = [:broil, :bake]

class Fish 
  COOKING_METHODS.each do |cook|
    define_method(cook) do |heat, time|
      # heat for time, etc
    end
  end
end

if !const_defined(:Squid)
  squid_class = Class.new(Fish)
  squid_class.name # => nil
  Object.const_set(:Squid, squid_class)
end

Besides inspecting objects in memory, you can modify them and create new ones.

Catch Yourself

class Fish 










end

  def method_missing(name, *args, &block)
    # last chance, what do you want to do!?
    super
  end
  def self.const_missing(name)
    # I'm sure we've got an extra 
    # `Fish::Head` around here somewhere...
    super
  end
yummy = Tuna.new(name: nil)
yummy.dolphin_safe?
# => I really can't afford another NoMethodError
if diner.high_class? || diner.russian?
  meal = Sturgeon::Caviar
end
# => do we have any of that?

When Ruby looks for some part of your program, but it isn't there, it's not too late. Ruby gives you hooks to handle those cases.

mruby

Ruby is wonderful because you have total control to express yourself in your code. You own it; not vice-versa.

 

Let's talk about another implementation of Ruby: mruby. In fact, this is Matz's current project.

Ruby everywhere

Matz's dream is to lower the barrier of entry to the "internet of things" by using Ruby to connect people to all kinds of computers.

What makes mruby special is that it's great for connecting to a) other applications or b) small computers.

Hello, mruby

I added this slide in place of the live demo, shoulda been there!

 

mruby's Hello world consists of: 

  • include mruby.h (the mruby runtime)
  • include mruby/compile.h (the mruby parser)
  • instantiate the VM (mrb_state)
  • use it to execute a string of code

 

See it on github

 

mruby Bytecode

I added this slide in place of the live demo, shoulda been there!

 

You don't have to ship your code with the mruby parser. You can precompile Ruby code to RiteVM instructions.

 

Then, your C application  can execute the bytecode instructions with the mruby VM.

 

See it on github

 

Ruby, meet hardware

I added this slide in place of the live demo, shoulda been there!

 

In your C application, you can prepare the mruby VM with values & code that are normally off-limits for Ruby. 

 

How about the timeless example of illuminating LEDs?

 

I don't have any LEDs, but let's imagine with `FakeLED`.

 

 

Ruby, meet Hardware

I added this slide in place of the live demo, shoulda been there!

 

You can  write a Ruby script to control your LEDs

(Ruby code, github)

 

First, wrap the hardware with some mruby-compatible functions

(C code, github)

 

Then, in your application, bind the hardware to the mruby VM by defining classes, methods and constants (github)

 

Lastly, evaluate your Ruby code with your VM instance (github)

mruby in the Wild

It looks like mruby has some support from Japanese companies.

Ex: forum.mruby.org, Toshiba, CloudWalk.io (not Japanese)

mruby recap

  • Lightweight Ruby built for embedding in C
  • RiteVM + bytecode
  • Many ways to run: 
    • from string
    • from bytecode
    • from external files
  • Interaction between C & Ruby
    • create Ruby objects & methods in C
    • call Ruby functions from C
  • Share code via mrb-gems
  • No documentation <3

Thanks for Listening

Robert Mosolgo, @rmosolgo

https://github.com/rmosolgo/mruby-examples

Made with Slides.com