Flowdock

Notes posted to Ruby

RSS feed
October 19, 2009
1 thank

Get all inner texts

Extend REXML::Element so that it can get the first text and following inner texts (child texts included) of the current element as array and as string:

class REXML::Element

 def inner_texts
  REXML::XPath.match(self,'.//text()')
 end

 def inner_text
  REXML::XPath.match(self,'.//text()').join 
 end

end
October 18, 2009
1 thank

Receiving data over UDP

It’s perfectly normal to receive ‘X’ strings with Ruby’s UDP sockets before the actual content.

Consider the following example:

require 'socket'

PORT = 5500

socket = UDPSocket.new
socket.bind('', PORT)

for i in 1..10
  IO.select([socket])
  p socket.recvfrom_nonblock(4096)
end

Now, sending data with netcat:

echo "Hello APIdock" | nc -vv -u 127.0.0.1 5500

The application would output:

["X", ["AF_INET", 61755, "localhost", "127.0.0.1"]]
["X", ["AF_INET", 61755, "localhost", "127.0.0.1"]]
["X", ["AF_INET", 61755, "localhost", "127.0.0.1"]]
["X", ["AF_INET", 61755, "localhost", "127.0.0.1"]]
["Hello APIdock\n", ["AF_INET", 61755, "localhost", "127.0.0.1"]]
October 10, 2009
2 thanks

Example

[5,6,7].each_with_index do |x,i|

puts "#{i} -> #{x}"

end

Outputs: 0 -> 5 1 -> 6 2 -> 7

October 9, 2009
0 thanks

Case-insensitive comparison

For a case-insensitive comparison, use String#casecmp

October 7, 2009
4 thanks

Hash#without

Here’s a small helper for doing the “opposite” of this method:

class Hash
  def without(*keys)
    cpy = self.dup
    keys.each { |key| cpy.delete(key) }
    cpy
  end
end

h = { :a => 1, :b => 2, :c => 3 }
h.without(:a)      #=> { :b => 2, :c => 3 }
h.without(:a, :c)  #=> { :b => 2 }
October 5, 2009
0 thanks

Using argument version in ruby < 1.8.7

The argument to this method was added in Ruby 1.8.7. If you want to use this form in an earlier version, you must instead use the slice! method.

It is mentioned up in the docs, but here it is again for reference:

# Ruby >= 1.8.7
p = list.pop(n)

# Ruby < 1.8.7
p = list.slice!(-n, n)
October 5, 2009
2 thanks

collect/map

If you’d like to use this method for something like Enumerable#collect, you are looking at the wrong place. This method will return the initial integer, not the values from the block.

a = 20.times { |n| n * 2 } #=> 20

Instead, use Range#collect:

a = (0...20).collect { n * 2 }
October 5, 2009
0 thanks

Shortcut with %

@tordans for multiple args wrap the args in an array

October 3, 2009
0 thanks

Shortcut with %

Thanks iamcata, that works :). And I finally found the right place to put this comment: http://apidock.com/ruby/String/%25#726-Use-it-with-HAML

October 3, 2009
1 thank

Use it with HAML

Like Henrik pointed out <a href=“http://henrik.nyh.se/2008/01/surround-helper-alternative-in-haml”>in his blogpost, this method is particulary useful when using HAML (http://haml-lang.com/) in Rails.

Instead of usind the HAML-Helper ‘surround’ (etc) you can just write

= "(%s)" % link_to("Edit", ...)

Or with two Arguments:

= "(%s, %s)" % ["Edit", "Delete"]

Thanks very much, Henrik!

October 2, 2009
1 thank

Shortcut

You can try:

“(%s %s)” % [“foo”, “bar”]

September 28, 2009
1 thank

Shortcut

According to http://henrik.nyh.se/2008/01/surround-helper-alternative-in-haml there is a short version for sprintf:

“(%s)” % “foo” is the same as sprintf(“(%s)”, “foo”)

Can someone who knows write more about this here? How do I work with multiple strings? Is this even possible? “(%s %t)” % “foo”, “bar” does not work.

September 9, 2009
1 thank

extend adds class methods too

Because classes are objects. So for example:

module Ispeak
  def says
    "greetings aliens!"
  end
end

module Ieat
  def eats
    "spinach"
  end
end

module Inhabitant
  def says
    "I'm strong to the finish"
  end
end

class Human
  extend Ispeak # add class methods from Ispeak
  include Inhabitant # add instance methods from Inhabitant
end

Human.extend Ieat # add class methods from Ieat

puts Human.says # -> greetings aliens!
puts Human.eats # -> spinach

popeye = Human.new

puts popeye.says # -> I'm strong to the finish
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
3 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