Posts tagged Ruby
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!
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.
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
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
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!
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.
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.

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!
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!
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!"
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.
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.
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
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
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.
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
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
|
|
|