Skip to content

Instantly share code, notes, and snippets.

@mickey
Created September 15, 2012 13:54
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mickey/3728045 to your computer and use it in GitHub Desktop.
Save mickey/3728045 to your computer and use it in GitHub Desktop.

Tips and tricks

ri documentation

With RVM:

#> rvm docs generate      # => takes some time ^^
#> ri Array
#> ri Array.push

Pry

def method(a)
   a + 2
end

show-method -l method      # l for line numbers

edit-method method

ls Array

stat Array#replace

show-doc Array#replace

Random value

Ruby 1.9 added Enumerable#sample(n):

[*1..100].sample(5)      # => [10, 14, 86, 29, 62]

Default values

def method(a, b=a); 
  "#{a} #{b}"
end

$> method 1
=> "1 1"

$> method 1, 2
=> "1 2"

Ruby 1.9 supports default argument at the beginning of a method:

def f(a=1, b)
  p [a,b]
end

p f(2)          # => [1, 2]

Ruby benchmark

The old fashion way:

beginning_time = Time.now
(1..10000).each { |i| i }
end_time = Time.now
puts "Time elapsed #{(end_time - beginning_time)*1000} milliseconds"

Ruby Benchmark module:

require "benchmark"
 
time = Benchmark.measure do
  (1..10000).each { |i| i }
end
puts time                     # => 0.010000   0.000000   0.010000 (  0.003298)

Benchmark.bm(100) do |x|
  x.report("each:")   { (1..10000).each { |i| i } }
  x.report("for:")    { for i in 0..10000; i; end}
  x.report("while:")  { i = 1; while i <= 10000; i+1; end }
end

Check string exist into another

x= "this is a test"
x['text']             # => false

Range to the end of an array

a = [*1..10]
a[6,:end]       # [6,7,8,9,10]

Any symbol will do :-)

How to call a proc

Ruby 1.9 supports 4 ways to call a proc:

f =-> n { n * 3}

p f[2]           # => 6
p f.call([1,2])  # => [1,2,1,2,1,2]
p f.("hoy ")     # => "hoy hoy hoy "
p f === 1        # => 3

Ternary operations

bottle = "whiskey"
drunk = (bottle == "beer" ? "NO" : "YUP")

is the equivalent of:

bottle = "whiskey"
drunk = ""
if bottle == "beer"
  drunk = "NO"
else
  drunk = "YES"
end

Percent notation

%w is for White-spaced delimited arrays %q works like Quotes %r wraps up nicely Regular expressions %x simply eXecutes system calls

%w{I like this a lot}       # => ["I", "like", "this", "a", "lot"]

%q{foo bar}                 # => "foo bar"

%r{^foo}.class              # => Regexp

%x{date}                    # => "Fri Sep 15 01:08:44 MST 2012\n"

Also, the delimiters {} I show can be a matching pair of delimiters, so you could use [], (), etc.

Ampersand and object notation

something {|i| i.foo }

Is the equivalent of

something(&:foo)

You'll often find it used with map and inject.

Array#*

Array#* supplied with a number multiplies the size of the array by using duplicate elements:

[1, 2] * 3 == [1, 2, 1, 2, 1, 2]

When given a string as an argument Array#* does a join!

%w{this is a test} * ", "                 # => "this, is, a, test"
h = { :name => "Fred", :age => 77 }
h.map { |i| i * "=" } * "n"              # => "age=77nname=Fred"

Formatting shortcuts

Decimal

grade = 10.5
"%.2f" % grade           # => "10.50"

Text

x = %w{p hello p}

"<%s>%s</%s>" % x                   # => "<p>hello</p>"
"<#{x[0]}>#{x[1]}</#{x[2]}>"        # => "<p>hello</p>"

"Here document" notation (or heredoc)

Another way to make a string:

string = <<-END
  on the one ton temple bell
  a moon-moth, folded into sleep,
  sits still.
END

the delimiter can be whatever you want:

raw = <<-SQL
  SELECT * FROM users;
SQL

raw = <<-XML
   <xml></xml>
XML

print <<-`EOC`    # => Yes! this executes the commands in the bock
  echo hi there
  echo lo there
EOC

Mass Assignements

a, b, c, d = 1, 2, 3, 4

def my_method(*args)
  a, b, c, d = args
end

Range is a class

(-5..-1).to_a      # => [-5, -4, -3, -2, -1]
('a'..'e').to_a    # => ["a", "b", "c", "d", "e"]

(10..15).to_a      # => [10, 11, 12, 13, 14, 15]
(10...15).to_a     # => [11, 12, 13, 14]

year = 1972
year = case year
  when 1970..1979: "Seventies"
  when 1980..1989: "Eighties"
  when 1990..1999: "Nineties"
end

Exception backtrace

do_division_by_zero =-> { 5 / 0}

begin
  do_division_by_zero.call
rescue => exception
  puts exception.backtrace
end

Awesome print

gem install awesome_print
$> require 'ap'
=> true
$> ap :a => 1, :b => 'greg', :c => [1,2,3]
{
    :a => 1,
    :b => "greg",
    :c => [
        [0] 1,
        [1] 2,
        [2] 3
    ]
}
=> {:a=>1, :b=>"greg", :c=>[1, 2, 3]}

Includes module in a single line

class MyClass
  include Module1, Module2, Module3    # => The modules are included in reverse order.
end

Shuffle plz!

[1,2,3].shuffle      # => [2,3,1]

Access to the gem documentation locally

$> gem server

Set Union

Join two arrays and remove all the duplicates:

[ "a", "b", "c" ] | [ "c", "d", "a" ] # => ["a", "b", "c", "d"]

Set intersection

Get all the elements that two arrays have in common:

[ 1, 1, 3, 5 ] & [ 1, 2, 3 ] # => [1, 3]

Naming the process

5.times do |i|
  $PROGRAM_NAME = "Hello from Octo.ly, iteration #{i}"
  sleep 3
end
$> ps aux | grep Octo

Clamp

#!/usr/bin/env ruby

require 'clamp'
require 'redis'
require 'time'
require 'pry'

class OctolyCommand < Clamp::Command

  subcommand "start", "Begin the class" do
    option ["-t", "--time"], "TIME", "time in minutes", default: 90
    def execute
      redis = Redis.new
      redis.set "octoly:start_time", Time.now.to_s
      redis.set "octoly:time_duration", time.to_i
    end
  end

  subcommand "status", "Where are we ?" do
    def execute
      redis = Redis.new
      start_time = Time.parse(redis.get("octoly:start_time"))
      duration = redis.get "octoly:time_duration"
      started_in_minutes = ((Time.now - start_time) / 60).round
      puts "Started #{started_in_minutes.round}mn ago"

      time_left = duration.to_i - started_in_minutes
      if time_left > 0
        puts "#{time_left}mn left to go"
      else
        puts "It's Over!"
      end
    end
  end

end

OctolyCommand.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment