Flowdock

Notes posted to Ruby

RSS feed
May 16, 2013
1 thank

Bug in Ruby or this documentation

%Q doesn’t return microseconds but milliseconds! Use %s%6N for microseconds.

April 17, 2013
0 thanks

@UnfalseIdeas

What is the purpose of

Hash[one: 1, two: 1]

When you can write

{one: 1, two: 2}

Aren’t you just passing a hash into the [] method?

April 4, 2013
1 thank

HTTPS request

Hey, guys!

You have one mistake in example code.

uri = URI('https://secure.example.com/some_path?query=string')

Net::HTTP.start(uri.host, uri.port,
  :use_ssl => uri.scheme == 'https').start do |http|
  request = Net::HTTP::Get.new uri.request_uri

  response = http.request request
end

Here HTTP::start method called twice. This code should look like

Net::HTTP.start(uri.host, uri.port,
  :use_ssl => uri.scheme == 'https') do |http|
  request = Net::HTTP::Get.new uri.request_uri

  response = http.request request
end

It’s work - I checked.

April 2, 2013 - (v1_8_6_287 - v1_9_3_392)
0 thanks

Passing in an Array instead of individual arguments

Pass in array instead of list

h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }

keys_i_want = %w(cow cat)

h.values_at(*keys_i_want) #=> ["bovine", "feline"]
April 2, 2013 - (v1_9_3_392)
0 thanks

output GBK

‘I am 中国人’.encode(‘gbk’,‘utf-8’)

April 2, 2013
0 thanks

you need kconv

require ‘kconv’

then

“中国人民很行”.toutf8

March 13, 2013
1 thank

Another Hash#without

Mange made me think, and I wanted to expand on his example with a small change.

class Hash
  def without(*keys)
    dup.without!(*keys)
  end

  def without!(*keys)
    reject! { |key| keys.include?(key) }
  end
end

h = { :a => 1, :b => 2, :c => 3 }
h.without(:a)      #=> { :b => 2, :c => 3 }
h #=> { :a => 1, :b => 2, :c => 3 }  

h.without(:a, :c)  #=> { :b => 2 }

h.without!(:a, :c) # { :b => 2 }
h #=> { :b => 2 }
March 5, 2013
0 thanks

Minor correction to Rubybull's examples?

Was your first example intended to be:

a=[11,22,31,224,44]
=> [11, 22, 31, 224, 44]
a.each.with_index { |val,index| puts "index: #{index} for #{val}" }
February 25, 2013 - (v1_9_3_125)
1 thank

Using the undef/replace param overwrites the fallback parameter

If you want to provide a fallback Hash / Proc / Object you must not define the :undef and/or replace params since they overwrite the fallback.

How fallback works

fallback = Hash.new { '?' }
fallback["\u2014"] = "-"
"\u2014".encode!("ISO-8859-15", fallback: fallback)
=> "-"

Undef overwrites fallback:

fallback = Hash.new { '?' }
fallback["\u2014"] = "-"
"\u2014".encode!("ISO-8859-15", fallback: fallback, undef: :replace, replace: '?' )
=> "?"
February 25, 2013
0 thanks

Where did this go?

For Ruby 1.9 and later, use Kernel#Array to get this functionality.

February 23, 2013
0 thanks

Modes listed in IO class

See class IO for file open modes

February 20, 2013
0 thanks

Freezing Time.now

You’d be much better off using the Timecop gem ( rubygems.org/gems/timecop ) than than manually writing monkey-patches to freeze Time.now etc.

It also supports time travel (i.e. changing the time, but allowing the clock to continue running).

February 3, 2013 - (v1_9_3_125)
0 thanks

How does enum#each_index differ from enum#with_each_index ?

Here is the working one each_with__index:

a=[11,22,31,224,44].each_with_index { |val,index| puts "index: #{index} for #{val}" if val < 30}
  index: 0 for 11
  index: 1 for 22
  => [11, 22, 31, 224, 44]

Below couldn’t produce the output, as with_index couldn’t work on the array.To make it workble, we need to first convert it to enumerator. And that can be done via the help of .to_enum, .each, or .map

a = [11,22,31,224,44].with_index { |val,index| puts "index: #{index} for #{val}" if val < 30}
=>NoMethodError: undefined method `with_index' for [11, 22, 31, 224, 44]:Array
       from (irb):2
       from C:/Ruby193/bin/irb:12:in `<main>'

Here is the working one with_index:

a = [11,22,31,224,44].each.with_index { |val,index| puts "index: #{index} for #{val}" if val < 30}
index: 0 for 11
index: 1 for 22
=> [11, 22, 31, 224, 44]
February 3, 2013 - (v1_9_3_125)
0 thanks

Difference between enum#with_object and enum#each_with_object

I found a very good post on SO - which clearly explained the difference between enum#with_object and enum#each_with_object. The link is as follows:

http://stackoverflow.com/questions/14671881/how-does-enumwith-object-differ-from-enumeach-with-object/14672305#14672305

February 2, 2013 - (v1_9_3_125)
1 thank

Enumerator#with_index has confusing documentation

Enumerator#with_index has confusing documentation, but hopefully this will make it clearer.

Code example

a=[11,22,31,224,44].to_enum
=> [11, 22, 31, 224, 44]
a.with_index { |val,index| puts "index: #{index} for #{val}" }
index: 0 for 11
index: 1 for 22
index: 2 for 31
index: 3 for 224
index: 4 for 44

a=[11,22,31,224,44].to_enum
=> #<Enumerator: [11, 22, 31, 224, 44]:each>
a.with_index(2){ |val,index| puts "index: #{index} for #{val}" if val > 30 }
index: 4 for 31
index: 5 for 224
index: 6 for 44
=> [11, 22, 31, 224, 44
January 14, 2013 - (>= v1_8_6_287)
0 thanks

Pass a block

While this example is not so obvious on first look what the block passed does, here’s a small explanation:

when the block is passed to this function, the uniqueness is checked based on a value returned by that block.

For example if it’s array of objects with “user_id” method, then this would be:

tasks.uniq{|t| t.user_id } # returns only tasks with unique user_id 
January 13, 2013
0 thanks

Note sure if doco is correct

(Note this was an issue in Ruby 1.9.2, 1.9.3 has been corrected, not sure why the generated doc is still incorrect)

Both exist? and exists? use the same underlying C function

file.c, line 5444

define_filetest_function("exist?", rb_file_exist_p, 1);
define_filetest_function("exists?", rb_file_exist_p, 1);

rb_file_exist_p does an rb_stat call, and just checks for no error.

rb_stat returns the result of a call to fstat, if the passed in value is a IO object, or stat (or your platforms equivalent). Both these return 0 on success, -1 on failure.

So both really just check that the underlying “thing” can respond to “stat” correctly. There are many things in a unix-style filesystem that have a “file” structure, not just traditional files. These functions help when you don’t care what type an entry is, just that it exists.

There doesn’t seem to be any difference in the two methods

File.directory? can test if a named file is a dir

December 10, 2012
1 thank

@drewyoung1

Including module in a class does not automatically over-write methods defined with the same name.

Ex:

module Mod

def exit(code = 0)
  puts "Exiting with code #{code}"
  super
end

end

class OriginalClass

include Mod
def exit
  puts "Original message"
end

end

OriginalClass.new.exit 99

Produces:

exit': wrong number of arguments (1 for 0) (ArgumentError)

if you use this construct, the alias_method will work similar to super:

module Mod

alias_method :super_exit, :exit
def self.included base
  base.instance_eval do
    def exit(code = 0)
      puts "Exiting with code #{code}"
      super_exit
    end
  end
end

end

December 7, 2012
0 thanks

Beware: default system crypt functionality silently ignores characters beyond the 8th

On some systems:

"1".crypt('aa')                     => "aacFCuAIHhrCM"
"12".crypt('aa')                    => "aa8dJzr7DFMPA"
"123".crypt('aa')                   => "aamrgyQfDFSHw"
"1234".crypt('aa')                  => "aatxRPdZ/m52."
"12345".crypt('aa')                 => "aajt.4s3e3SZA"
"123456".crypt('aa')                => "aaAN1ZUwjW7to"
"1234567".crypt('aa')               => "aaOK9MRbwVNmQ"
"12345678".crypt('aa')              => "aaNN3X.PL2piw"
"123456789".crypt('aa')             => "aaNN3X.PL2piw"
"1234567890".crypt('aa')            => "aaNN3X.PL2piw"
"1234567890abcdefghij".crypt('aa')  => "aaNN3X.PL2piw"
November 14, 2012
0 thanks

What artemave said.

I’d remove my original note if I could, but I can’t see a way how.

October 17, 2012
1 thank

See also: Rack::Utils.parse_nested_query.

Note that CGI::parse does not attempt to create a multi-level object; that is, it basically ignores hard brackets in key names.

For a method that does deal with these, see Rack::Utils.parse_nested_query.

October 10, 2012 - (>= v1_9_1_378)
1 thank

Bad Example

@nZifnab it is a bad example because an included module is basically a class.

module Mod
    def exit(code = 0)
        puts "Exiting with code #{code}"
        super
    end
end

include Mod

exit 99

produces

Exiting with code 99
September 10, 2012
0 thanks

Reports originally defined method names, not invoked names in Ruby 1.9.x

In Ruby 1.8.7, the reported method names were those of the methods actually invoked, so if #b was an alias for #a, and #b was called, it would be reported as “… in `b’”. In Ruby 1.9, the same invocation is now reported as “… in `a’”.

Unfortunately, this change disables the hack that could formerly be used to create a variant of __method__ that returns the method as actually invoked. The new __callee__ method is no help with that, because it is currently synonymous with __method__.

September 10, 2012
0 thanks

__callee__ and __method__ both return symbol when originally defined, not current

There has been some indication that __callee__ is intended to return the symbol with which the method was actually invoked, whereas __method__ returns name with which the method was originally defined, but __callee__ actually behaves identically to __method__ in Ruby 1.9.1 1.9.2, and 1.9.3.

This distinction is meaningful, because methods can be aliased after they are created.

In Ruby 1.8.7, it was possible (though) not convenient to get the name of the method as actually invoked, by calling another method that extracts the name from caller.first. Even that hack no longer works in Ruby 1.9 though, since it will return the originally defined method name as well.

August 6, 2012
0 thanks

What it do?

For those favoring YAML outputs, this methods simply and recursively outputs the keys and values in YAML (into a String) for your pleasure.

July 23, 2012
2 thanks

Long-wanted functional extension

This is pretty nice method allowing you to build stuff in a functional way.

Lets say you want to build a hash from an array, keyed by array object, where each value is the number of same objects in the array.

# imperative style :-P

h = Hash.new(0)
[1, 3, 2, 3, 1, 3].each { |i| h[i] += 1 }
h # => {1=>2, 3=>3, 2=>1} 

# functional style, using inject. Note that you need to explicitly return the accumulator in the end

[1, 3, 2, 3, 1, 3].inject(Hash.new(0)) { |a, i| a[i] += 1; a } 
# => {1=>2, 3=>3, 2=>1} 

# using each_with_object. Note the reversed block params - accumulator is the last parameter. 
# Mnemonic: consistent with each_with_index, where object is the first parameter

[1, 3, 2, 3, 1, 3].each_with_object(Hash.new(0)) {|i, a| a[i] += 1}
# => {1=>2, 3=>3, 2=>1} 
July 19, 2012
0 thanks

Assignment using 'key: value'

Another shorthand way of assigning key, value pairs:

Hash[one: 1, two: 2] #=> {:one=>1, :two=>2}
June 28, 2012
0 thanks

see also – similar methods

See also DateTime#strftime and Date#strftime . (They work similarly, but have different APIdock notes.)

June 28, 2012
0 thanks

see also – similar methods

See also Time#strftime and DateTime#strftime . (They work similarly, but have different APIdock notes.)