Notes posted to Ruby

RSS feed
August 24, 2009
1 thank

Getting (n..end)

It would seem like it would be possible to say, get everything from element i and to the end by saying

# WRONG!
a[i, -1] # "From 2 to the last element"

but since the second parameter does not say the ending index, but instead the length, this is not possible and you will get nil from the above code.

What you should do instead is using that the length can be specified longer then how long it is going to be:

b = [1, 2, 3]
# Return up to a million elements
# (not "return an array WITH 1 million elements")
b[2, 1_000_000] #=> [3]

# Size is guaranteed to never be shorter
# than our returned value should be
a[i, a.size]

It is a waste to do something like this:

a[i, a.size - i]
a[i..(a.size-i)]
August 20, 2009
4 thanks

Symbol#to_proc

@tadman - or simply defining:

class Symbol
  def to_proc
    proc { |obj, *args| obj.send(self, *args) }
  end
end
August 17, 2009
1 thank

Freezing Time.now with Time.is

Sometimes when writing unit tests/specifications our code sets an attribute of an object using Time.now because running specs/test takes time.

The solution is to “freeze” Time.now with the following Time.is method:

class Time

  def self.metaclass
    class << self; self; end
  end

 # useful for unit testing
 # Time.is(Time.now) do
 #   Time.now # => Tue Nov 13 19:31:46 -0500 2007
 #   sleep 2
 #   Time.now # => Tue Nov 13 19:31:46 -0500 2007
 # end
 #
 # Time.is("10/05/2006") do
 #   Time.now # => Thu Oct 05 00:00:00 -0400 2006
 #   sleep 2
 #   Time.now # => Thu Oct 05 00:00:00 -0400 2006
 # end
  def self.is(point_in_time)
    new_time = case point_in_time
               when String then Time.parse(point_in_time)
               when Time then point_in_time
               else raise ArgumentError.new("argument should be a string or time instance")
               end
    class << self
      alias old_now now
    end
    metaclass.class_eval do
      define_method :now do
        new_time
      end
    end
    yield
    class << self
      alias now old_now
      undef old_now
    end
  end

end

It’s a good idea to add this to your spec_helper/test_helper and “freeze” time whenever you’re testing functionality that depends on a specific time value.

August 13, 2009
0 thanks

no overwrite

const_set does not overwrite, it only create new ones

August 11, 2009
2 thanks

Common signals

Some of the more commonly used signals:

1       HUP (hang up)
2       INT (interrupt)
3       QUIT (quit)
6       ABRT (abort)
9       KILL (non-catchable, non-ignorable kill)
14      ALRM (alarm clock)
15      TERM (software termination signal)
August 6, 2009
2 thanks

Second example is correct

@taryneast, the second example is correct. The receiver’s #size limits the result’s.

nachokb

August 3, 2009 - (v1_8_6_287)
0 thanks

Using YAML

YAML library must be required.


Example to display an array as yaml formatted output

require 'yaml'

puts [100, [99, 98, 97], 96, 95].to_yaml
July 31, 2009 - (v1_8_7_72)
1 thank

Example

File.exist?(“/path/to/file_or_dir”)

July 31, 2009 - (v1_8_7_72)
0 thanks

synonym

Synonym for File.exist?

July 27, 2009
0 thanks

Include the 'abbrev' module

To get this access to this method you must:

require 'abbrev'
July 17, 2009
0 thanks

Like Groovy Expando

If you’re coming from Groovy/Grails: this is called an Expando in Groovy.

July 17, 2009
1 thank

Highlight keywords in a text

Case-insensitive

keywords.inject(text) { |text, keyword| text.gsub(/(#{keyword})/i, "<strong>\\1</strong>") }

<strong> can be replace by whatever HTML tag you want for hightlighting (<b>, <i>, …)

July 16, 2009
0 thanks

Usage example

Usage example:

cube = lambda {|x| x * x * x } 
cube.call(3)  # => 27
cube.call(6)  # => 216
July 14, 2009
2 thanks

Not for floats

You should use assert_in_delta when comparing floating-point numbers.

July 13, 2009
1 thank

Any base logarithm

Using basic arithmetic you can get logarithm with any base:

def log_with_base base, num
  Math.log(num) / Math.log(base)
end

Examples:

>> log_with_base 2, 10
=> 3.32192809488736
>> log_with_base 2, 2
=> 1.0
>> log_with_base 2, 4
=> 2.0
>> log_with_base 2, 16
=> 4.0
>> log_with_base 4, 16
=> 2.0
July 13, 2009
0 thanks

Any base logarithm

Using basic arithmetic you can get logarithm with any base:

def log_with_base base, num
  Math.log(num) / Math.log(base)
end

Examples:

>> log_with_base 2, 10
=> 3.32192809488736
>> log_with_base 2, 2
=> 1.0
>> log_with_base 2, 4
=> 2.0
>> log_with_base 2, 16
=> 4.0
>> log_with_base 4, 16
=> 2.0
July 8, 2009
1 thank

This is an alias

Please comment under the real method instead: find_index

July 8, 2009 - (<= v1_8_7_72)
5 thanks

Using block version in Ruby < 1.8.7

The block usage was added in 1.8.7, so to get the same functionality in an earlier version of Ruby, you need to utilize the find method.

Here is a quick example:

match = list.find { |l| l.owner == myself }
match_index = list.index(match)

If you do some gymnastics, you can have it on one line without extra variables:

match_index = list.index(list.find { |l| l.owner == myself })
July 1, 2009
4 thanks

Example

User = Struct.new(:name, :phone)

marc = User.new(“Marc”, “555-5555”)

June 25, 2009
2 thanks

Antonym of empty?

The antonym of empty? is Enumerable#any? method:

[].empty?  #=> true
[].any?    #=> false
[1].empty? #=> false
[1].any?   #=> true

Be cautious however, if your array might contain nil’s or false’s:

[false, nil].any? #=> false
June 10, 2009
0 thanks

list of predefined variables

$! The exception information message set by ‘raise’. $@ Array of backtrace of the last exception thrown.

$& The string matched by the last successful pattern match in this scope. $` The string to the left of the last successful match. $‘ The string to the right of the last successful match. $+ The last bracket matched by the last successful match. $1 to $9 The Nth group of the last successful regexp match. $~ The information about the last match in the current scope.

$= The flag for case insensitive, nil by default. $/ The input record separator, newline by default. $\ The output record separator for the print and IO#write. Default is nil. $, The output field separator for the print and Array#join. $; The default separator for String#split.

$. The current input line number of the last file that was read. $< The virtual concatenation file of the files given on command line. $> The default output for print, printf. $stdout by default. $_ The last input line of string by gets or readline.

$0 Contains the name of the script being executed. May be assignable. $* Command line arguments given for the script sans args. $$ The process number of the Ruby running this script. $? The status of the last executed child process. $: Load path for scripts and binary modules by load or require.

$“ The array contains the module names loaded by require. $DEBUG The status of the -d switch. $FILENAME Current input file from $<. Same as $<.filename. $LOAD_PATH The alias to the $:. $stderr The current standard error output. $stdin The current standard input. $stdout The current standard output. $VERBOSE The verbose flag, which is set by the -v switch. $-0 The alias to $/. $-a True if option -a (”autosplit“ mode) is set. Read-only variable. $-d The alias to $DEBUG. $-F The alias to $;. $-i If in-place-edit mode is set, this variable holds the extension, otherwise nil. $-I The alias to $:. $-l True if option -l is set (”line-ending processing“ is on). Read-only variable. $-p True if option -p is set (”loop“ mode is on). Read-only variable. $-v The alias to $VERBOSE. $-w True if option -w is set.

Source: http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Variables_and_Constants#Pre-defined_Variables

May 27, 2009
0 thanks

Potentially slow operation

Remember that checking for a value is a potentially slow operation (all the elements might be iterated) as oposed to querying a key (e.g. with has_key?), which is supposed to be fast in a Hash.

May 27, 2009 - (>= v1_8_6_287)
3 thanks

map_with_index

If you want to access the element index when using map, you can do it with enum_for:

(1..6).enum_for(:each_with_index).map { |v, i| "index: #{i} value: #{v}" }
#=> ["index: 0 value: 1", "index: 1 value: 2", "index: 2 value: 3", "index: 3 value: 4", "index: 4 value: 5", "index: 5 value: 6"]
May 26, 2009
1 thank

Potentially slow operation

Remember that checking for a value is a potentially slow operation (all the elements might be iterated) as oposed to querying a key (e.g. with has_key?), which is supposed to be fast in a Hash.

May 20, 2009
0 thanks

Symbol Keys Only

While OpenStruct#new is rather indifferent to the kind of keys submitted, marshal_load requires Symbol keys only. Use of a string can cause difficulty.

To fix:

marshal_load(hash.inject({ }) { |h, (k,v)| h[k.to_sym] = v; h })

As a note, Rails has the Hash#symbolize_keys method that can be used in place.

May 19, 2009
0 thanks

Method functions like Hash#merge!

This method functions a lot like Hash#merge! only with a different name.

f = OpenStruct.new
# => #<OpenStruct>
f.marshal_load({:foo => 'bar'})
# => #<OpenStruct foo="bar">
f.foo
# => "bar"
May 19, 2009
2 thanks

Like JavaScript Object

For those familiar with JavaScript naked Objects, this is very similar.

May 13, 2009
3 thanks

Equivalent to Array#reject!

This method is functionally identical to Array#reject!

May 7, 2009
0 thanks

question?

Shouldn’t the second example be:

[1,2].zip(a,b)         #=> [[1, 4, 7], [2, 5, 8], [nil,6,9]]

??? or am I missing something?

May 7, 2009 - (v1_8_6_287 - v1_8_7_72)
0 thanks

Reg Ex Syntax

Is there any place where there is a full listing of RegEx syntax?