Notes posted to Ruby
RSS feedBad example
Note that it would be better to avoid the alias_method line in the example and just call super.
Doesn't return nil on empty array when param is given
This does not return nil if the array is empty and n is given.
[].shift(2) # => [] a = [] a.shift(2) # => [] a # => []
Interpolating
Note that to interpolate, the sequences must be inside single quotes:
# replace /ll/ with itself 'hello'.gsub(/ll/, '\0') # returns 'hello' 'hello'.gsub(/ll/, "\0") # returns 'he\000o'
at_exit in sintra
in main.rb of sinatra:
at_exit { Application.run! if $!.nil? && Application.run? }
RE: Replacing with "\" and match — a simple solution
Thanks. No, I am not trying to quote for a regex. It was mostly an approach thing since I came into contact with the behavior previously when I played around. After doing some tests, I figured I should spare any other adventurers that part. :-)
Time.now in UTC
A quick way to get the current time in UTC is:
Time.new.utc # => Wed Mar 24 14:38:19 UTC 2010
collect_with_index
Use Object#enum_for if you need to collect with index:
require 'enumerator' ['a', 'b', 'c'].enum_for(:each_with_index).collect do |item, index| "#{index}: #{item}" end
See also: Enumerable#each_with_index
collect_with_index
Use Object#enum_for if you need to collect with index:
require 'enumerator' %w{foo bar}.enum_for(:each_with_index).collect do |item, index| "#{index}: #{item}" end
See also: Enumerable#each_with_index
Create new Hash as subset of another a different way
or
only keys
old_hash = { :a => 'A', :b => 'B', :c => 'C', :d => 'D', :e => 'E', :f => 'F' } only_keys = [ :a, :c, :f ] new_hash = old_hash.delete_if { |k, v| !only_keys.include? k }
only values
old_hash = { :a => 'A', :b => 'B', :c => 'C', :d => 'D', :e => 'E', :f => 'F' } only_values = [ 'A', 'D', 'G' ] new_hash = old_hash.delete_if { |k, v| !only_values.include? v }
there are many ways to skin a cat :)
Create new Hash as subset of another
old_hash = {:a=>‘A’,:b=>‘B’,:c=>‘C’,:d=>‘D’,:e=>‘E’,:f=>‘F’}
only_keys = [:a,:c,:f]
new_hash = Hash[*old_hash.find_all{|k,v| only_keys.member?(k)}.flatten]
# => {:a=>“A”, :c=>“C”, :f=>“F”}
or for values
only_vals = [‘A’,‘D’,‘G’]
new_hash = Hash[*old_hash.find_all{|k,v| only_vals.member?(v)}.flatten]
# => {:a=>“A”, :d=>“D”}
Another Example
Delete all files in log
require 'FileUtils' Dir["log/*"].each{|file| FileUtils.rm file}
Complete Formatting Codes
%a - The abbreviated weekday name (“Sun”)
%A - The full weekday name (“Sunday”)
%b - The abbreviated month name (“Jan”)
%B - The full month name (“January”)
%c - The preferred local date and time representation
%C - Century (20 in 2009)
%d - Day of the month (01..31)
%D - Date (%m/%d/%y)
%e - Day of the month, blank-padded ( 1..31)
%F - Equivalent to %Y-%m-%d (the ISO 8601 date format)
%h - Equivalent to %b
%H - Hour of the day, 24-hour clock (00..23)
%I - Hour of the day, 12-hour clock (01..12)
%j - Day of the year (001..366)
%k - hour, 24-hour clock, blank-padded ( 0..23)
%l - hour, 12-hour clock, blank-padded ( 0..12)
%L - Millisecond of the second (000..999)
%m - Month of the year (01..12)
%M - Minute of the hour (00..59)
%n - Newline (n)
%N - Fractional seconds digits, default is 9 digits (nanosecond)
-
%3N millisecond (3 digits)
-
%6N microsecond (6 digits)
-
%9N nanosecond (9 digits)
%p - Meridian indicator (“AM” or “PM”)
%P - Meridian indicator (“am” or “pm”)
%r - time, 12-hour (same as %I:%M:%S %p)
%R - time, 24-hour (%H:%M)
%s - Number of seconds since 1970-01-01 00:00:00 UTC.
%S - Second of the minute (00..60)
%t - Tab character (t)
%T - time, 24-hour (%H:%M:%S)
%u - Day of the week as a decimal, Monday being 1. (1..7)
%U - Week number of the current year, starting with the first Sunday as the first day of the first week (00..53)
%v - VMS date (%e-%b-%Y)
%V - Week number of year according to ISO 8601 (01..53)
%W - Week number of the current year, starting with the first Monday as the first day of the first week (00..53)
%w - Day of the week (Sunday is 0, 0..6)
%x - Preferred representation for the date alone, no time
%X - Preferred representation for the time alone, no date
%y - Year without a century (00..99)
%Y - Year with century
%z - Time zone as hour offset from UTC (e.g. +0900)
%% - Literal “%” character
t = Time.now #=> 2007-11-19 08:37:48 -0600 t.strftime("Printed on %m/%d/%Y") #=> "Printed on 11/19/2007" t.strftime("at %I:%M%p") #=> "at 08:37AM"
Complete Formatting Codes
NOTE: Some of these seem only to work for DateTime (e.g. %L, %N)
%a - The abbreviated weekday name (“Sun”)
%A - The full weekday name (“Sunday”)
%b - The abbreviated month name (“Jan”)
%B - The full month name (“January”)
%c - The preferred local date and time representation
%C - Century (20 in 2009)
%d - Day of the month (01..31)
%D - Date (%m/%d/%y)
%e - Day of the month, blank-padded ( 1..31)
%F - Equivalent to %Y-%m-%d (the ISO 8601 date format)
%h - Equivalent to %b
%H - Hour of the day, 24-hour clock (00..23)
%I - Hour of the day, 12-hour clock (01..12)
%j - Day of the year (001..366)
%k - hour, 24-hour clock, blank-padded ( 0..23)
%l - hour, 12-hour clock, blank-padded ( 0..12)
%L - Millisecond of the second (000..999)
%m - Month of the year (01..12)
%M - Minute of the hour (00..59)
%n - Newline (n)
%N - Fractional seconds digits, default is 9 digits (nanosecond)
-
%3N millisecond (3 digits)
-
%6N microsecond (6 digits)
-
%9N nanosecond (9 digits)
%p - Meridian indicator (“AM” or “PM”)
%P - Meridian indicator (“am” or “pm”)
%r - time, 12-hour (same as %I:%M:%S %p)
%R - time, 24-hour (%H:%M)
%s - Number of seconds since 1970-01-01 00:00:00 UTC.
%S - Second of the minute (00..60)
%t - Tab character (t)
%T - time, 24-hour (%H:%M:%S)
%u - Day of the week as a decimal, Monday being 1. (1..7)
%U - Week number of the current year, starting with the first Sunday as the first day of the first week (00..53)
%v - VMS date (%e-%b-%Y)
%V - Week number of year according to ISO 8601 (01..53)
%W - Week number of the current year, starting with the first Monday as the first day of the first week (00..53)
%w - Day of the week (Sunday is 0, 0..6)
%x - Preferred representation for the date alone, no time
%X - Preferred representation for the time alone, no date
%y - Year without a century (00..99)
%Y - Year with century
%z - Time zone as hour offset from UTC (e.g. +0900)
%% - Literal “%” character
t = Time.now #=> 2007-11-19 08:37:48 -0600 t.strftime("Printed on %m/%d/%Y") #=> "Printed on 11/19/2007" t.strftime("at %I:%M%p") #=> "at 08:37AM"
Use message param
The message param is invaluable in case test fails – if you use it to display relevant info, you will find out what went wrong much faster.
Reworking the silly example above:
assert some_list.include?(5)
will only tell you that
<false> is not true.
which isn’t terribly helpful, is it? But if you use message like that:
assert some_list.include?(5), "some_list = #{some_list.inspect}"
the output will be:
some_list = [1, 2]. <false> is not true.
which in most cases should give you strong hints as to why the test failed.
Eagerness
Check out this simple example:
"Hello Ruby friend".sub(/^(.*)e/, 'X') # => "Xnd" "Hello Ruby friend".sub(/^(.*?)e/, 'X') # => "Xllo Ruby friend"
The question mark turns the dotstar into non-eager mode which means it will halt on the first subsequent “e” rather than the last one. This comes in handy e.g. for Cucumber step definitions.
Okay, but not really nice:
/^I am using rvm "([^\"]*)" with gemset "(.*)"$/
Much more readable and consistent equivalent to the above:
/^I am using rvm "(.*?)" with gemset "(.*?)"$/
Deprecated in 1.9.x!
Use FileUtils::copy instead. It is also in 1.8.x, FileUtils, so call that one instead.
makedirs(path) to create file path
mkdir will only create a single directory on an existing path. If you want to create a full path, like the `mkdir -p /full/path` command, use the makedirs method.
1.8: File.makedirs(path) 1.9: FileUtils.makedirs(path)
Hash#except
Note that the ActiveSupport library provides the except and except! methods, which return the Hash minus the given keys. So you don’t need to write your own wrapper if you happen to be using Rails or ActiveSupport as a stand-alone library:
http://apidock.com/rails/ActiveSupport/CoreExtensions/Hash/Except/except
Re: POST DATA
The ampersand is more common, but the W3C recommends that all web servers support semicolon separators in the place of ampersand separators:
http://www.w3.org/TR/1999/REC-html401-19991224/appendix/notes.html#h-B.2.2
Using Unshift with Load Path's
Using unshift on your load path’s for Rails, Sinatra, etc, is a good way of ensuring that the file your including is going to be first.
Example
vendor = File.join(File.dirname(__FILE__), 'vendor') $LOAD_PATH.unshift File.expand_path(File.join(vendor, 'ultraviolet-0.10.5', 'lib'))
Odd Number of padding characters
In the case of an odd number of empty spaces in a length, Ruby will append the extra character to the right-hand side of the string.
Example:
irb(main):002:0> "Hello".center(10,"-") => "--Hello---"
Clarification of argument
The description should read:
The argument is the salt string, which must be at least two characters long, each character drawn from [a-zA-Z0-9./].
Rmoving preceding 0's
In most *nix system, adding a - after the % will remove preceding 0s.
So %-d for a single digit day, or %-I for a single digit hour, etc.
File name without the extension
To get the file name without the extension you can use File.extname in combination with File.basename
File.basename("test.rb", File.extname("test.rb")) #=> "test" File.basename("a/b/d/test.rb", File.extname("a/b/d/test.rb")) #=> "test" File.basename("test", File.extname("test")) #=> "test" File.basename(".profile", File.extname(".profile")) #=> ".profile"
For the file path use File.dirname
File.dirname provides what File.basename omits.
Interesting usage for polymorphic asset model :)
…to automatically define default scopes of inherited classes.
class Asset < ActiveRecord::Base belongs_to :resource, :polymorphic => true before_save :set_asset_type def set_asset_type self.asset_type = self.class.name end def self.inherited(subclass) super subclass.send(:default_scope, :conditions => "asset_type='#{subclass.name}'") end end
Argument Accepted
Accepts a single argument record_separator which is the character or string to chomp.
Why isn’t this shown in the method def at the top?