Posts tagged Ruby


December 20, 2011 by Dave

We recently created a new ruby gem called fletcher. It's a cross- website product/item information fetcher. To use fletcher, all you have to do it pass it a url to a product on one of favorite websites. You'll get back an easy-to-use ActiveRecord-like object(a Hashie::Mash) that contains useful information about that product, including its name, description, images, etc. Let's see it in action.

item = Fletcher.fetch

item.name # => "Avenir Deluxe Unicycle (20-Inch Wheel)"

item.description # => "A wonderful unicycle"

item.image # => {:url => "http://ecx.images-amazon.com/images/I/41b3TNb3uCL._SL500_AA300_.jpg", :alt => "Picture of 
Unicycle"}

item.image.url # => "http://ecx.images-amazon.com/images/I/41b3TNb3uCL._SL500_AA300_.jpg"

We originally wrote fletcher for use in our wishlist-sharing website, WishlistFactory, so you would only need to enter the url of a gift you want, and the gift information would automatically be fetched and included on your wishlist. We thought other people might find this useful, so we packaged it up as a gem and released it to the public.

The source code of fletcher is also on github, so if you'd like to add a supported website to fletcher, or make any other changes, feel free to fork it!

0 Comments
Tags:


September 15, 2011 by Dave

OmniAuth is a great gem for OAuth authentication in any rack application such as Ruby on Rails, Sinatra, etc. If you're using it in Rails, I wrote a handy little initializer that will automatically load in your OAuth provider credentials from a yaml config file instead of defining them directly in the initialzer.

# config/providers.yml
providers:
  google:
    key: CONSUMER_KEY
    secret: CONSUMER_SECRET 
  facebook:
    key: APP_ID
    secret: APP_SECRET
  twitter:
    key: CONSUMER_KEY
    secret: CONSUMER_SECRET

# config/initializers/omniauth.rb
if Rails.env != 'test'  
  config = YAML::load(File.open(Rails.root.join, "config", "providers.yml")))
  if config && !config.empty?
    Rails.application.config.middleware.use OmniAuth::Builder do        
      config["providers"].each do |name, credentials|
        provider name.to_sym, credentials["key"], credentials["secret"], {:client_options => config[:client_options]}       
      end
    end
  end
end

This makes it easy to add/delete providers by editing the providers.yml config file.

0 Comments


August 24, 2011 by Dave

Here's a quick whenever schedule.rb file for of you who are using bundler to run rake commands(via bundle exec).

job_type :bundle_exec, 'cd :path && bundle exec :task :output' # :path is set to project dir by default

every 1.hours do
  # bundle_exec "rake [task]"
  bundle_exec "rake log:clear"
end
0 Comments
Tags:


March 11, 2011 by Dave

Have you ever wanted to use a Ruby Time object in javascript? Well, now you can! Add this to any ruby script, or if you're using rails, add this to config/initializers/time.rb, and you'll be good to go!

class Time
  def to_js # to javascript, ie: "2007-06-09T14:23:11", usage: new Date("<%= Time.now.to_js %>")
     self.strftime("%Y-%m-%dT%H:%M:%S")
  end
end
0 Comments


November 11, 2010 by Dave

If you're working with Ruby and Mysql, chances are you'll probably need to work with DATETIMES. Here's a quick way  to convert the current time(or any other Ruby Time object) into a MySQL-compatible string:

Time.now.strftime("%Y-%m-%d %H:%M:%S") # => "2010-11-12 11:41:35"

If you're using Ruby on Rails, You can take this a step further by adding a custom method to the Time class definition. Just add this to config/initializers/time.rb to convert regular DateTimes to a mysql format for use in mysql conditions:

# Add custom time helpers
class Time
  def to_mysql # add custom time formatting
   self.strftime("%Y-%m-%d %H:%M:%S")
  end
end

Then you can pull a mysql DateTime string from any object(as long as it has a created_at or updated_at field which is auto-updated):

>> User.find(1).created_at.to_mysql
=> "2010-11-10 23:04:53"

That's it!

1 Comments


November 04, 2010 by Dave

Hey ruby programmers, have you ever wanted to create methods for classes and modules in realtime, outside of class definitions?  If there's no method for something you just called, no biggie! Just create it out of the blue using dynamic methods.

When defining a method in ruby, you can do it two different ways, using define_method or def. Here's an example of how you'd normally define a method with the two.

# This example shows how to define a method for a class using define_method
class Test
  define_method(:test) do 
    puts "Testing..."
  end
end

Test.new.test # => "Testing..."
# This example shows how to define a method for a class using def
class Test
  def test
    puts "Testing..."
  end
end

Test.new.test # => "Testing..."

As you can see, they do almost the same thing.  Let's get to the good stuff! You can easily create methods dynamically using def or define_method. There's a variety of ways to do this, but in this example I'll be using class_eval. You can also use instance_eval to create static class methods too.

In these examples, I'm placing the method creation code inside of method_missing, which is automatically called by ruby when a method cannot be found.

Here's an example using define_method:

# This example shows how to define a method for a class and all of its instances. 
# This methods uses define_method 
class Test
  attr_accessor :name
  def initialize(name)
    @name = name
  end
  
  def method_missing(m, *args)
      puts "#{@name} - No #{m}, so I'll make one..."
      self.class.class_eval  do |*args|
        define_method(:test) do |*args|
           puts "#{@name} - I'm now calling the method test. #{args}"
        end
      end 
  end
end

test1 = Test.new("test1")
test2 = Test.new("test2")

test1.test
test1.test
test2.test("Hey!")

Here's an example using def:

# This example shows how to define a method for a class and all of its instances. 
# This methods uses def
class Test
  attr_accessor :name
  def initialize(name)
    @name = name
  end
  
  def method_missing(m, *args)
      puts "#{@name} - No #{m}, so I'll make one..."
      self.class.class_eval  do 
        def test(arg1 = "")
           puts "#{@name} - I'm now calling the method test. #{arg1}"
        end
      end 
  end
end

test1 = Test.new("test1")
test2 = Test.new("test2")

test1.test
test1.test
test2.test("Hey!")
Both of these output:
test1 - No test, so I'll make one...
test1 - I'm now calling the method test.
test2 - I'm now calling the method test. Hey!

As you can see, you can also pass in an argument set using both of these methods. Dynamic methods may not be necessary for every application, but they can definitely be handy!

You can read more about the magic of method_missing here.

0 Comments
Tags:


November 02, 2010 by Dave

Ruby is a clever programming language. As you can probably tell from all the ruby posts here, we use ruby a lot. Today I'm going to tell you about method_missing. When you call a method(aka message) in ruby, if it exists, it gets executed and everything is skippy. However, what if that method doesn't exist? Well, ruby raises/throws an NoMethodError exception, like so:

undefined method `myUnknownMethod' for nil:NilClass (NoMethodError)

However, before this happens, ruby tried to look for a method called method_missing. If it exists, it gets called. This means that you can handle any unknown method that might get passed to one of your classes. ActiveRecord uses method_missing to find models for people who don't like to write their own methods or queries for ActiveRecord::Base.find.

If you'd like to see how method_missing works, here's a little script I threw together to demonstrate how it works:

class MyClass
  def self.myMethod
    puts "Hello."
  end
  
  def self.method_missing(method_id, *arguments_you_tried_to_pass_in)
    puts "No Method Found.\nYou tried to run: #{method_id}\nWith the arguments: #{arguments_you_tried_to_pass_in.inspect}"
  end
end

MyClass.myUnknownMethod("some weird string", 27)

This returns:

No Method Found.
You tried to run: myUnknownMethod
With the arguments: ["some weird string", 27]

method_missing is pretty handy, eh?

There's also 10 things you should know about method missing that Max points out. Check it out.

0 Comments


October 26, 2010 by Dave

In ruby, there's a handy shortcut you can use if you're going to pass an unknown(variable-length) number of arguments into a method. All you have to do is place an asterisk before the multiple argument variable name in a function, like so...

def some_method(*args)
  puts args.inspect
end
some_method('1','2',3,[4,5,6], {:x => 1}, 2, 3)

This is a very handy tool that you don't see in a lot of languages. In many programming languages asterisks are usually used with pointers(which then access memory addresses), but don't make this mistake in Ruby.

The asterisk in ruby is used only for handling multiple arguments in a function. That's it. You can't use them in any other scope than an argument block. For instance, if you tried this...

def some_method(*args)
 puts *args.class
end
some_method('1','2',3,[4,5,6], {:x => 1}, 2, 3) 

...Your script will fail from a syntax error. You can, however, pass the argument block into any class or instance methods. Check out this handy script from misuse:

def my_method(*args)
  # this line unrolls all the arguments out of the array
  # otherwise you'd be passing in an array to sub_method (see below)
  puts "Arguments received by sub_method as individual items:"
  sub_method(*args)


  # here we don't unroll the arguments so you can see the receiver
  # just gets an array instead of a series of arguments
  puts "Arguments received by sub_method as single array:"
  sub_method(args)
end

def sub_method(*args)
  args.each do |arg_item|
    puts arg_item.inspect
    puts arg_item.class
  end
end

my_method('1','2',3,[4,5,6], {:x => 1}, 2, 3)

Which returns...

Arguments received by sub_method as individual items:
"1"
String
"2"
String
3
Fixnum
[4, 5, 6]
Array
{:x=>1}
Hash
2
Fixnum
3
Fixnum
Arguments received by sub_method as single array:
["1", "2", 3, [4, 5, 6], {:x=>1}, 2, 3]
Array

Rails uses asterisk functionality with many of their methods, and they use a handy method to extract hash values from a variable length argument set, which are then placed in a pretty options hash. It's called extract_options!.


Support for variable length arguments is a very useful tool indeed. If you're a ruby programmer, don't be afraid to try it out!

0 Comments
Tags:


August 10, 2010 by Dave

Setting default values for variables can be very useful in ruby. There are a variety of ways to do it and the way you assign default values all depends on how the value is being stored. Here's some examples:

Default variables in a method or function:

def print_my_name(name = "John Doe")

puts name

end

print_my_name # => "John Doe" 

This is the old fashioned way to set default variables in a method...Sure, it works, but it has one major drawback. The values you pass into this method have to be order, which can be annoying if you want to assign only one custom value in a method, and that arguments is at the end of the list of arguments passed into the method. Instead, I like to pass in a hash of value into a method and then handle default value assignment inside the method, instead of in the the method definition:

def print_my_name(options = {})

options[:name] ||= "John Doe"

puts options[:name]

end

print_my_name :name => "John Doe" #  => "John Doe"

This lets you pass in any value as you please, in any order, since everything is stored in a hash! This also has a slight downside to it: Since we're working with hash members, we have to assign default values to hash items the right way. This can vary depending on the data type of the variable. We can't Let's take a look:

def print_my_information(options = {})

  options[:name] ||= "John Doe" # default value for a string

  options[:age]    ||= 25 # default value for an integer/float

  options[:hates_pickles]    = true if options[:hates_pickles].nil?  # default value for a bool

  return options

end

print_my_information :name => "Dave", :age => "28", :hates_pickles => false # => {:age=>"28", :hates_pickles=>false, :name=>"Dave"}

I like to use ruby's ||=  operator, which checks a variable to see if it's defined, nil, or false. This works great for strings, chars, integers, and floats, but is horrible for booleans values(aka bools) because if you pass in a value for a bool that's false, it will get reassigned if you use the ||= operator, so never use this operator for default bool values. ever. If you make reference to an undefined hash item, ruby will return nil, so we can assign default bool values by checking if the hash key you're looking for is nil:

 

options[:hates_pickles] = true if options[:hates_pickles].nil?

 

This is one good way to handle default values in an method in ruby, and can come in very handy!

 

3 Comments
Tags:


Here's another approach to replacing text strings in files recursively(in all subdirectories). This approach uses linux's replace command instead of sed, and Ruby's Find module to get a list of all files in the current directory(including all subdirectories). This script will handle any special regexp characters as well.

#!/usr/bin/env ruby

# Recursive String Replacement - Approach 2, starting in current dir.
# Author: Dave Hulihan

require 'find'

def get_dirs # get all directories(recursive), starting in current 
 dir_array = Array.new 
 Find.find('./') do |f| 
 	dir_array << f if !File.directory?(f) # add only non-directories
 end
 return dir_array
end

if ARGV.length < 2
        puts "Usage: recursive_replace \"[string1]\" \"[string2]\""
        exit 0
end

@string1 = ARGV[0]
@string2 = ARGV[1]

puts "Replacing #{@string1} with #{@string2}..."
directories = get_dirs
for directory in directories
  if directory && directory != "." && directory != ".." 
	  exec_string = "replace \"#{@string1}\" \"#{@string2}\" -- #{directory}"
	  #puts "In #{directory}"
	  # puts exec_string 
	  system(exec_string)
  end
end


puts "Done!"

2 Comments
Tags:


Have you ever been working in linux, and you wanted to replace a certain string of text with another string of text, from several files, in several directories? Well, now you can!  Normally you can do this using linux's sed or replace command, but they don't work well when you want to recursively descend into subdirectories. Here's a quick ruby script I wrote that will take two arguments, the old string(you want replaced) and the new string(that will do the replacin'):

#!/usr/bin/env ruby

require "eregex"

# Recursive String Replacement, starting in current dir.
# Author: Dave Hulihan

if ARGV.length < 2
        puts "Usage: recursive_replace [string1] [string2]"
        exit 0
end

@string1 = ARGV[0]
@string2 = ARGV[1]

puts "Replacing #{@string1} with #{@string2}..."

@string1 = Regexp.escape(@string1) # escape any special characters
@string2 = Regexp.escape(@string2)

exec("find ./ -type f | xargs sed -i 's/#{@string1}/#{@string2}/g'")

puts "Done!"

This script uses linux's find and sed commands together to perform a recursive file search with string replacement. 

 

1 Comments
Tags:


If you ever need to get a common element from a group of arrays in Ruby, normally  you can use the & operator to compare two arrays, which returns elements that are present or common in both arrays. This is all good, except when you're trying to get common elements from more than two arrays. However, I want to get common elements from an unknown, dynamic number of arrays, which are stored in a hash.

Using the inject() method in ruby, which cycles through items of a container(like arrays and hashes), here's how you can accomplish this:

def get_common_elements_for_hash_of_arrays(hash) # get an array of common elements contained in a hash of arrays, for every array in the hash.
    return hash.values.inject{|acc, elem| acc & elem}  # inject & operator into hash values.
end

example_hash = {:item_0 => ["1","2","3"], :item_1 => ["2","4","5"], :item_2 => ["2","5","6"] }
puts  get_common_elements_for_hash_of_arrays(example_hash) # => ["2"]

This is an easy way to get common items or elements from a group or hash of different arrays, and this code can also easily be adapted to search an array of arrays.
1 Comments
Tags:


March 25, 2010 by Dave

Do you ever find yourself programming in ruby, and you have two arrays, and you want to compare them against each other? Here's a couple of helpful array operators you can use that will show you which elements are common to two arrays, which are different, and more:

  array1 = ["x", "y", "z"]
  array2 = ["w", "x", "y"]

  array1 | array2 # Combine Arrays & Remove Duplicates(Union)
  => ["x", "y", "z", "w"]

  array1 & array2  # Get Common Elements between Two Arrays(Intersection)
  => ["x", "y"]

  array1 - array2  # Remove Any Elements from Array 1 that are contained in Array 2.(Difference)
  => ["z"]
You can also check out a bunch of other helpful array tricks here: http://sites.google.com/site/dhtopics/Home/ruby-essentials/advanced-ruby-arrays
4 Comments
Tags:


October 27, 2009 by Dave

In Ruby, you can easily convert a string, or any kind of text, into a Class. Here's a quick example:

class_name = "new_class" # set string with name of class, will camelize to NewClass 
new_object = class_name.camelize.constantize.new # call NewClass.new
0 Comments
Tags:


October 28, 2009 by Dave
Here's a quick ruby script that will generate a file full of random data. You may be wondering...why would anyone want a bunch of random numbers? Well, we use this kind of data to make sample graphs in different programs and to simulate data results that a particular piece of hardware should be reporting(like data a sensor would report). We often write software for scientific devices that spew forth tons of data. This script generates example data that such devices might spew, so we know how to handle it on the software side of things.

This is a simple ruby script that asks the user for a couple specifications for the data that will be generated. It asks the user for the amount of numbers to generate, the range of values to generate from, the filename to store the data in, and how it should be delimited(comma or newline).

Here's the code:
#!/usr/bin/ruby

# Random Data Generator 
# Author: Hulihan Applications
# Purpose: Uh, To generate random data 
  
def get_keyboard_input(options = {})
  options[:default] ||= "default" # set options[:default]'s  default 
  input = STDIN.gets
  input = input.chomp
  input = options[:default] if (input.size == 0 && input.to_i == 0) # return the default value if user pressed enter without entering anything.
  return input 
end

# This script generates random data for graphing function. Delimiting options: comma, newline
puts "Generating Random Data...\n"

puts "How Many Numbers do you want to generate?(default is 100)"
@number = get_keyboard_input(:default => 100)

puts "Number values will be generated randomly What is the Minimum value?(default is 0)"
@min_value = get_keyboard_input(:default => 0)

puts "Number values will be generated randomly What is the Minimum value?(default is 100)"
@max_value = get_keyboard_input(:default => 100)

puts "What is the filename to store the data in?(default is data.txt, if file exists, data will be concatenated at EOF)"
@filename = get_keyboard_input(:default => "data.txt")

puts "What kind of delimiter would you like, comma or newline?(default is newline)"
@delimiter = get_keyboard_input(:default => "newline")

puts "Add tab-delimited ids, yes or no?(default is no)"
@add_ids = get_keyboard_input(:default => "no")

puts "Generating #{@number.to_i} numbers between #{@min_value} and #{@max_value}..."

file = File.new(@filename, "a+")

# generate data
for i in 1..@number.to_i
  if @add_ids.downcase == "yes" || @add_ids.downcase == "y" # add tab-delimited ids
    file.print "#{i}\t"
  end
  file.print rand((@max_value.to_i + 1) - @min_value.to_i) + (@min_value.to_i) # write the random data from a range. We add 1 to @max_value because rand(100) would only give up to 99
  # write delimiter 
  if @delimiter.downcase == "newline"
     file.print "\n"
  elsif @delimiter.downcase == "comma"
     file.print "," unless i == @number.to_i # add comma unless last value in file
  end
end

puts "File: #{@filename} saved successfully!"
file.close
This script should be ran from command line(in windows, mac os, or linux). Here's an sample of what it looks like when it's running:
$ ruby generate_random_data.rb


Generating Random Data...
How Many Numbers do you want to generate?(default is 100)
1000
Number values will be generated randomly What is the Minimum value?(default is 0)
55
Number values will be generated randomly What is the Minimum value?(default is 100)
60
What is the filename to store the data in?(default is data.txt, if file exists, data will be concatenated at EOF)
my_random_data.txt
What kind of delimiter would you like, comma or newline?(default is newline)
comma
Add tab-delimited ids, yes or no?(default is no)
no
Generating 1000 numbers between 55 and 60...
File: my_random_data.txt saved successfully!
I just thought i'd share, as this may be useful for people that need any amount of random data to use.
0 Comments
Tags:


April 01, 2008 by Dave
 I was looking around for a quick couple of lines of code that would search out any string for a swear word and replace it with a cleaner word. I had a little trouble finding an easy example, so here's one for you. I use a modified version of this script for a lot of my applications:

 $ nano filter_swear_words.rb

#!/usr/bin/ruby
@string = "What the funk"

@bad_words = Hash.new
@bad_words[:funk] = "funny" #the [:funk] is the bad word, and the "funny" is the replacement@bad_words[:shoot] = "shucks" # add more in this fashion 

@seperated_words =  @string.split(" ") # seperate content by spaces

print "Original String: #{@string}\n"

@cleaned_string = ""

for word in @seperated_words
 @bad_words.each do |bad_word, replacement|
  if word == bad_word.to_s # if the word we're looking at is bad

   word = replacement # replcae the word 

   else # the word is we're looking at is okay
   end
 end

 @cleaned_string << word + " "
end

print "Cleaned String: #{@cleaned_string}\n"

So when we run the script, here's what we get:

$ ruby filter_swear_words.rb
Original String: What the funk
Cleaned String: What the funny
0 Comments
Tags:


December 21, 2007 by Dave

    In most other languages(java, c++, etc.), when you create an object, you have to define the variables that will make up the structure of the object. You also usually add a getter(retrieves the variable) and a setter(sets/writes the contents of the variable) so you can access the variable. 

However, in Ruby, you only need one line of code that will do all of the above:

attr_accessor :myvar 

This creates the getter and setter methods from the variable, which(by default) look like this:

def myvar #this is the getter
	@myvar #returns the contents of @myvar
end

def myvar=(anything) #this is the setter
	@myvar = anything #set the contents of myvar to anything!
end

You're also looking at the code to override the methods, too!  Example: If you want to create a backup variable whenever you create the original, do this:

app/model/example.rb 

Class Example 
        attr_accessor :myvar 

        def myvar=(anything) #this is the setter

           @myvar_backup = @myvar #backup the original variable

           @myvar = anything #set the contents of myvar to anything! 
        end
 end

script/console

@myExample = Example.new
=> #<Example:0x2b50b2c3d560>
> @myExample.inspect # see what the object has
=> "#<Example:0x2b50b2c3d560>"
>> @myExample.myvar = "hello!" # set the variable
=> "hello!"
>> @myExample.inspect # see what the object has now
=> "#<Example:0x2b50b2c3d560 @myvar_backup=\"hello!\", @myvar=\"hello!\">"

Also, if you just wanted the getter or setter only, you would use:

attr_reader :myvar 
# or
attr_writer :myvar 

 Read more about accessors: 

http://www.ruby-doc.org/docs/UsersGuide/rg/accessors.html

6 Comments