Ruby is Full of Surprises


@JanLelisMay 2018Ruby Unconf

idiosyncratic-ruby.com

Documenting lesser-known features in Ruby


begin with an easy program.
you should be able to write
a program unless for you,
program in ruby language is
too difficult. At the end
of your journey towards the
ultimate program; you must
be a part of a programming
language. You will end if
you != program


2nd place in the Ruby TRICK competition of 2015,
by Shinichiro Hamaji


$ ruby -c poem.rb # => Syntax OK

PoLS

Principle of Least Surprise

…when you know Ruby
…very, very, very vell

By Yusuke Endoh, the master of esoteric programming

Monumental Quine

Surpring Method Behavior

Question 3

There is a String#split method,
which also accepts regexes:


"rug-b".split(/-/) #=> ["rug", "b"]
            

What will happen if we use a capturing group in the regex?


  "rug-b".split(/(-)/) #=> ?
              

Question 3


"rug-b".split(/(-)/) #=> ["rug", "-", "b"]
            

Bonus Question 3

What will happen if we use a multiple capturing groups?


"rug-b".split(/((-))/) #=> ?
            

Bonus Question 3

What will happen if we use a multiple capturing groups?


"rug-b".split(/((-))/) #=> ["rug", "-", "-", "b"]
            

Bonus Bonus


"rug-b".split(/(((((-)))))/)
#=> ["rug", "-", "-", "-", "-", "-", "b"]
            

"rug-b".split(/-(?=(.))/)
#=> ["rug", "b", "b"]
            

String#succ

There is a String method that will generate the successor of a string


"aaa".succ #=> "aab"
            

What's the result of:


"9z".succ #=> ?
              

"9z".succ #=> "10a"
            

Bonus

What's the result of:


"z9".succ #=> ?
            

  "z9".succ #=> "aa0"
            

Surprising Interfaces

…new features were added when needed

…sometimes with terrible naming

Script Lines

There is a feature in Ruby...

Is it?

script_lines

SCRIPT_LINES

__SCRIPT_LINES

__script_lines__

SCRIPT_LINES__

Ruby::DebugInfo::SCRIPT_LINES

Script Lines


  SCRIPT_LINES__ = {} unless defined? SCRIPT_LINES__
            

SCRIPT_LINES__

WEIRD. What gives with the trailing underscores?
It’s such a big constant that it leaves a two-character shadow!!
why the lucky stiff

Surprising Object Representation


module A
end

class B
  def initialize
    p 42
  end
end

A, B = B, A
            

A.new  #=> #<B:0x00000002744008>
# 42
            

require 'stringio'
def shuffle_ruby(n=rand(50))
  mod, os, e, sio = Module, ObjectSpace, Exception, StringIO
  stderr, $stderr = $stderr, sio.new
  n.times{
    begin
      m1 = os.each_object(mod).to_a.sample
      m2 = os.each_object(mod).to_a.sample
      puts "Swap #{m1} and #{m2}"
      eval "#{m1}, #{m2} = #{m2}, #{m1}"
    rescue e
    end
  }
  $stderr = stderr
  puts "Ruby shuffled (#{n} swaps)"
end
            

Surprising CLI Options

IRB Inspectors

Specify how IRB results are displayed

IRB Inspectors


$ irb -f --inspect yaml
irb(main):001:0> [42]
=> ---
- 42
            

IRB Inspectors


$ irb -f --inspect marshal
irb(main):001:0> 42
=> i/
            

IRB Inspectors


$ irb -f --inspect "{ |r| r.to_s.reverse }"
irb(main):001:0> 42
=> 24
            

IRB Inspectors


# in lib/irb/context.rb
case opt
# ...
when /^\s*\{.*\}\s*$/
  begin
    inspector = eval "proc#{opt}"
  rescue Exception
    puts "Can't switch inspect mode(#{opt})."
    return
  end
  self.inspect_mode = inspector
            

Surprising Future

Ruby will not get boring \o/


Infinite ranges: 0..


Classes definitions can start with uppercased Unicode letters!

class ℛ𝘂ᖯʏ
  def initialize
    # …
  end
end

From Ruby Quiz


How many ways does Ruby provide to embed a NULL Byte?

Hint: For example, "\x00" embeds a null byte


A: 40

Bonus Question

What?

"\0" "\x00" "\x0" "\u0000" "\u{0000}" "\u{000}" "\u{00}" "\u{0}" "\u{00000}" "\u{000000}" "\000" "\00" "\C-0" "\C-\x00" "\C-\x0" "\C-\000" "\C-\00" "\C-@" "\C-\x40" "\C-\100" "\C-`" "\C-\x60" "\C-\140" "\C- " "\C-\x20" "\C-\40" "\c0" "\c\x00" "\c\x0" "\c\000" "\c\00" "\c@" "\c\x40" "\c\100" "\c`" "\c\x60" "\c\140" "\c " "\c\x20" "\c\40"

Thank You!

idiosyncratic-ruby.com

@JanLelis