Archive for category Ruby

gem install mysql on Mac OSX Leopard with RVM

I installed RVM a few months back and messed around with it for a minute, but I did not try out Rails 3 beta with it. I have been researching Rails 3 a good bit lately, and I decide that it would be worth it to upgrade most of my apps to Rails 3, since it has so many appealing new features… especially the plugin API.  I have Ruby 1.8.6 installed on my box and you need a version greater than 1.8.7 (I think) in order to run Rails 3.  RVM is an easy way to run multiple versions of Ruby on the same box without conflicts.   So I fired up my shell and checked to see if RVM was working:

>rvm list

This returned my system ruby and nothing else. So I decided to install 1.9.1

>rvm install 1.9.1

It went thru the process and took a few minutes to download, configure and compile it. After it was complete I fired off this command:

>rvm 1.9.1
>ruby -v

From there I could see that I was in fact using Ruby 1.9.1 instead of 1.8.6 which was originally installed on my Mac. VERY COOL! I proceeded to install rails –pre and everything seemed to be working fine until I created a rails app and did some tests. It was complaining that I needed to install mysql 2.8.1 in order for activerecord to work. Note that in RVM, your gems are installed in a separate directory for each Ruby version that you install. Then I proceeded to install the mysql gem

>gem install mysql
Building native extensions.  This could take a while...
ERROR:  Error installing mysql:
        ERROR: Failed to build gem native extension.

/Users/johnmcaliley/.rvm/rubies/ruby-1.9.2-preview3/bin/ruby extconf.rb
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lm... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lz... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lsocket... no
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lnsl... no
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lmygcc... no
checking for mysql_query() in -lmysqlclient... no
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

Provided configuration options:
        --with-opt-dir.............yada,yada,yada..........

Damn! I have seen that before.. way back when I first set up my Mac to run Rails 2.3.2. ohh.. so I need to tell it where mysql is. I searched G and found what was working for other people (Note: change -arch to your type system):

>sudo env ARCHFLAGS="-arch i386" gem install mysql -- \
>   --with-mysql-dir=/usr/local/mysql --with-mysql-lib=/usr/local/mysql/lib \
>   --with-mysql-include=/usr/local/mysql/include

Doh! Still not working.. I get the same error. So I proceeded to search and search to find the right way to do this. Here are some decent resources I ran across and they may help your particular situation, but nothing seemed to work for me.
http://wonko.com/post/how-to-install-the-mysqlruby-gem-on-mac-os-x-leopard
http://adamyoung.net/gem-install-mysql-OSX
http://movesonrails.com/journal/2010/4/21/rvm-installing-the-mysql-gem-ruby-191-under-osx.html(I think there are some typos in this blog and it appears rake-compiler is what you really need at the end)

So after a few hours of wanting to punch my screen, I decided to remove RVM, do a fresh install and try again.

>sudo rvm implode

This should remove RVM and all the files under $HOME/.rvm/
Actually… I did it without sudo first and it removed rvm, but not the .rvm directory under my home… so I had to sudo rm -Rf ~/.rvm

I followed the instructions on the RVM install page and it installed it just fine. This time I installed the lastest version of Ruby which is 1.9.2 (yes I tried that with RVM before I uninstalled it too and it did not work).

>rvm install 1.9.2
>rvm 1.9.2
>sudo env ARCHFLAGS="-arch i386" gem install mysql -- \
>   --with-mysql-dir=/usr/local/mysql --with-mysql-lib=/usr/local/mysql/lib \
>   --with-mysql-include=/usr/local/mysql/include

Worked like a charm… So I guess it was something with my original install of RVM. I must have configured it wrong or something.. When all else fails, start from scratch.

Tags: , ,

Iterate over a date range in Ruby

I am trying to pull some reporting data from an API. I can only call it for one day at a time, since the API does not accept a date range. In order to use a date range I will have to make multiple calls to the API. Ruby can easily accomplish this be iterating thru a range of dates. I am going to pass a date range as 2 strings to my method and it will convert the strings to dates and iterate over the entire date range, and then call the API for each date. If no dates are passed to the method, then it assigns yesterday as the start and end date automatically. You can add some stuff for error checking for start date>end_date, but thats out of the scope for this tut. The Date class makes this really easy by giving us the upto method. It does all the work behind the scenes and you dont have to worry about crap like skipping the leap year.

Check it out:

def get_report_data(start_date=Time.now.yesterday,end_date=Time.now.yesterday)
  start_date.to_date.upto(end_date.to_date) do |day|
    get_data(day)
  end
end

Simplified with just a loop that prints dates:

"01/01/2010".to_date.upto("01-31-2010".to_date) do |day|
  puts day
end

Tags: , ,

star symbol in front of Ruby def argument

you may have seen something like this and wondered what the star symbol inside the argument parenthesis was:

def some_method(*args)
  #cowboy code goes here
end

The star symbol in front of args means that this method can accept an unlimited number of arguments. This is commonly used in Ruby on Rails when extracting options from the method arguments:

options = args.extract_options!

extract_options! is an ActiveSupport method that pulls out the option hashes from the method arguments.

Tags: ,

Ruby programming – what is dollar sign colon .unshift ($:.unshift) ??

This is a special variable in ruby. Ruby special variables start with the dollar sign followed by a single character. This particular variable is the default search path for load or require. If you call it in irb or the rails console, you can see it returns an array of strings which are paths.

Since it returns an array, the unshift is simply an array method that adds an object to the beginning of an array.

An example of this can be seen in the ActiveRecord source (2.3.2 rails). In this particular example, the ActiveSupport path is prepended to the array, so that it can be required in the code.

activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
if File.directory?(activesupport_path)
  $:.unshift activesupport_path
  require 'active_support'
end

There are a bunch of other special variables in ruby like this one. Take a look here for more info: http://www.zenspider.com/Languages/Ruby/QuickRef.html#18

Tags: , ,

Ruby If statements – all objects are true, except FalseClass (false)

This was a bit confusing to me since I was used to programming in other languages. Basically every object has a boolean value with is true, unless the object is false or nil. Even the integer 0 will return true if you put it into an “if” expression. Take a look at some examples:

# STRING TEST
if "test"
  p "true"
else
  p "false"
end
=>"true"

#FIXNUM TEST
if 0
  p "true"
else
  p "false"
end
=>"true"

#FalseClass TEST
if false
  p "true"
else
  p "false"
end
=>"false"

#NIL TEST
if nil
  p "true"
else
  p "false"
end
=>"false"

I find this logic especially useful when passing an options hash inside a function. It allows you to use an if expression on the option and it will always return true, unless that object is nil or has been set to false. This allows you to test if an option exists by writing only:

if option[:some_option]
  # do something
end

Anyways.. I just thought that was a pretty cool feature, compared to other languages

Ruby Module Mixin Awesomeness

The deeper I dig into Rails, the more I need to know about Ruby.  I have been learning more about how Ruby does OO.  I came to Ruby from Java and at first things like modules were confusing for me.  Recently I discovered the power of mixin modules.  I was trying to figure out how to put my models into a plugin and then override or add additional functionality to those models.  My main reason for doing this was to change the database referenced in the “use_db” plugin.  I had a hard time finding an elegant way to do it, but mixin modules really helped me do it in simple way.

So what do mixin modules do?  Basically they allow you to code instance methods into a module and then include the module in a class.  The class will then have access to the instance methods in a module.  Pretty nice when you have shared functionality between models.  You can code one module and include it in several models.

Here is an example:

module LoudModule
  def explode
    "BOOM!"
  end
end

class BottleRocket
  include LoudModule
end

class FireCracker
  include LoudModule
end

firecracker = FireCracker.new
p firecracker.explode

bottlerocket = BottleRocket.new
p bottlerocket.explode

As you can see firecracker and bottlerocket both have access to the “explode” instance method in the module.

Now to make this work with a Rails plugin where you need a model base class:

module BaseWidget
  self.included?(base)
    base.belongs_to :manufacturer
  end

  def some_instance_method
    "test"
  end
end

class Widget < ActiveRecord::Base
  unloadable
  use_db :prefix => "mydatabse_prefix_"
  include BaseWidget
  def some_new_instance_method
    "test2"
  end
end

This is pretty cool because it will allow you to define a base class for your model that you can reuse in different applications. The self.included? block allows you to load use the instance methods from the base class (ActiveRecord::Base in this case). So Widget will have access to all the associations, named_scopes and act_as* methods from the Base class.

Using Ruby Threads

I have a fairly simple Ruby script that downloads 2 very large files from 2 different locations.  Long story short.. it is cheaper for me from a bandwidth perspective (b/c of 95th percentile billing) to download both of the files at the same time.  I can’t exactly do this in my Ruby script if I write it that executes sequentially.  So I thought back to my Java days (YUCK!)  and decided to see if Ruby had a similar mechanism as Java for threading.  Turns out it does and its pretty easy to use.  My requirements are to download both files and continue with the script only after both files are downloaded.  So here is what I did:

#create a thread to download first file
t1 = Thread.new do

system(“/usr/local/bin/ruby /path/to/my/file/start_download.rb”)

end

#start the 2nd download

start_download2

while t1.status!=false

sleep 1

end

#continue

…….

Easy enough. I start by firing off a thread to download the first file, then I start download the 2nd file within the main script.   Then I check the status of the thread to see if its complete.  If so, I continue the execute of the main script.

Tags: ,