Best ruby questions in August 2010

sqlite3-ruby install error on Ubuntu

18 votes

I have the following error during sqlite3-ruby install:

Building native extensions.  This could take a while...
ERROR:  Error installing sqlite3-ruby:
    ERROR: Failed to build gem native extension.

/usr/bin/ruby1.8 extconf.rb
checking for sqlite3.h... no
sqlite3.h is missing. Try 'port install sqlite3 +universal' or 'yum install sqlite3-devel'
*** 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
    --without-opt-dir
    --with-opt-include
    --without-opt-include=${opt-dir}/include
    --with-opt-lib
    --without-opt-lib=${opt-dir}/lib
    --with-make-prog
    --without-make-prog
    --srcdir=.
    --curdir
    --ruby=/usr/bin/ruby1.8
    --with-sqlite3-dir
    --without-sqlite3-dir
    --with-sqlite3-include
    --without-sqlite3-include=${sqlite3-dir}/include
    --with-sqlite3-lib
    --without-sqlite3-lib=${sqlite3-dir}/lib


Gem files will remain installed in /usr/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.3.1 for inspection.
Results logged to /usr/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.3.1/ext/sqlite3/gem_make.out

sqlite3.h is located in /usr/include/

sudo gem install sqlite3-ruby --without-sqlite3-include=/usr/include

doesn't work


ERROR:  While executing gem ... (OptionParser::InvalidOption)
    invalid option: --without-sqlite3-include=/usr/include

Ubuntu 10.04

Aha-ha!

sudo apt-get install build-essential ;)

Could node.js replace Ruby on Rails completely in the future?

16 votes

I'm not very updated in the event-driven/concurrency area in node.js. I wonder, is it possible that node.js would replace Ruby on Rails completely in the future?

Or is it more like an extension to Ruby on Rails for the real time features?

I'm not sure exactly what you mean by "could replace". Ruby on Rails and Node.js really have nothing to do with each other, so it doesn't make sense to compare them. Ruby is a programming language and Rails is a web application framework. Node.js is neither a language nor an application framework, it's an asynchronous I/O library.

There are asynchronous I/O libraries for Ruby as well, like EventMachine or Cool.IO for example. And of course there's Twisted for Python, Async, Event and EV for Perl, Rx for .NET, Async Computation Expressions for F# and libaio, libevent and libev for C. (BTW: Node.js is actually implemented using libev.) Node.js isn't even the only such library for ECMAScript, there's a port of Rx for ECMAScript as well. It would make much more sense to compare those to Node.js than Ruby on Rails.

(If you really want to compare Ruby on Rails to something, compare it to Express.js, which is a web framework built on top of Node.js. Although it actually is more akin to Sinatra or maybe Padrino than Rails. Otherwise the comparison doesn't make sense: the only thing that Ruby on Rails and Node.js have in common is that both are Turing-complete, and in some sense everything that is Turing-complete can replace everything else, but that's not a particularly useful result.)

So, Node.js really is nothing special. Evented I/O has been around for a very long time, and there are many stable and mature (much more so than Node.js, in fact!) implementations for just about any language on earth. In fact, Node.js itself actually uses libev and libeio.

The thing that makes Node.js different from all those other libraries is ECMAScript. Actually, the thing that makes Node.js so great is that ECMAScript is crap, or more precisely that the ECMAScript standard library is crap. In ECMAScript, you practically can't do anything: you can't read files, load scripts, access the network. You can't even access the friggin' web, which is kind of ironic for a web scripting language.

When you are within the event loop, you cannot make any blocking calls. However, pretty much the entire Ruby IO, File and Dir classes, as well as the networking and database libraries and so on are all mostly synchronous and blocking. (And the same is true for pretty much all of the other languages as well.) So, when you write code in EventMachine or Cool.IO or Twisted, you have to be very careful which methods you call and which libraries you use in order to avoid accidentally making blocking I/O calls.

In ECMAScript, you cannot accidentally make blocking I/O calls, because you simply can't make any I/O calls at all: there are no I/O functions in the ECMAScript standard library.

Which means that any I/O functions you might want to call, have to be specifically implemented for Node.js. And obviously, if you implement it specifically for Node.js, you do it in an asynchronous fashion. That's what distinguishes Node.js from, say, EventMachine or Twisted: the fact that the entire I/O library was built from the ground up for Node.js. If you wanted to do that for EventMachine, you would first have to rip out the entire existing Ruby I/O library and then rebuild it from scratch. In ECMAScript, there's nothing to rip out and nothing to rebuild. You simply start with the "right" design from day one.

And that's exactly what Ryan did.

Another difference between EventMachine and Node.js is that Ruby programmers are typically trained in a synchronous mindset. ECMAScript programmers however, usually start their career with the DOM, which is completely asynchronous. (Ever wondered what the A in AJAX stands for? Asynchronous JavaScript and XML!) So, they never even know that something like synchronous I/O even exists! It's like that old joke about learning Chinese: it can't be that hard, even two year old Chinese kids speak it …

Can't find rake on Ruby Rails Install

13 votes
Microsoft Windows [Version 6.0.6002]
Copyright (c) 2006 Microsoft Corporation.  All rights reserved.

C:\Windows\system32>gem install rake
Successfully installed rake-0.8.7
1 gem installed
Installing ri documentation for rake-0.8.7...
Installing RDoc documentation for rake-0.8.7...

C:\Windows\system32>rake
C:/Program Files (x86)/Ruby192/lib/ruby/1.9.1/rubygems.rb:340:in `bin_path': can
't find executable rake for rake-0.8.7 (Gem::Exception)
        from C:/Program Files (x86)/Ruby192/bin/rake:19:in `<main>'

C:\Windows\system32>

Why can't my system find the rake command? Where should I start debugging the problem?

Update 1

I'm using ruby 1.9.2 and installed it using the ruby installer for windows (http://rubyinstaller.org/)

This issue is a problem of Ruby 1.9.2 bundled version of Rake. You will need to remove the included rake.gemspec from the gem specification folder.

See this thread at RubyInstaller group, and specifically this link from Ruby-Forums for the solution.

BTW: a recommendation: avoid installing Ruby into path with spaces (Program Files). I forsee lot of problems with your installation in the future.

In Ruby, what is the equivalent to an interface in C#?

11 votes

I'm currently trying to learn Ruby and I'm trying to understand more about what it offers in terms of encapsulation and contracts.

In C# a contract can be defined using an interface. A class which implements the interface must fulfil the terms within the contract by providing an implementation for each method and property (and maybe other things) defined. The individual class that implements an interface can do whatever it needs within the scope of the methods defined by the contract, so long as it accepts the same types of arguments and returns the same type of result.

Is there a way to enforce this kind of thing in Ruby?

Thanks

A simple example of what I mean in C#:

interface IConsole
{
    int MaxControllers {get;}
    void PlayGame(IGame game);
}

class Xbox360 : IConsole
{
   public int MaxControllers
   {
      get { return 4; }
   }

   public void PlayGame(IGame game)
   {
       InsertDisc(game);
       NavigateToMenuItem();
       Click();
   }
}

class NES : IConsole
{
    public int MaxControllers
    {
        get { return 2; }
    }

   public void PlayGame(IGame game)
   {
       InsertCartridge(game);
       TurnOn();
   }
}

There are no interfaces in ruby since ruby is a dynamically typed language. Interfaces are basically used to make different classes interchangeable without breaking type safety. Your code can work with every Console as long it behaves like a console which in C# means implements IConsole. "duck typing" is a keyword you can use to catch up with the dynamic languages way of dealing with this kind of problem.

Further you can and should write unit tests to verify the behavior of your code. Every object has a respond_to? method you can use in your assert.

Should I host gems in GitHub or RubyGems?

10 votes

I've read that RubyGems is de-facto hosting for gems.

I host all my Rails projects on GitHub.

So my questions are:

  • Are there any reasons for hosting my gems on GitHub and not RubyGems?

  • Does RubyGems have private repositories like GitHub?

  • I've read that jeweler is nice for creating gem skeleton. On their webpage it sounds like it uploads these gems to GitHub and not RubyGems. But didn't GitHub removed the Gem support?

  • This railscast http://media.railscasts.com/videos/183_gemcutter_and_jeweler.mov shows us how to use gemcutter to manage gems. But Gemcutter.org is now RubyGems.org right? But still a gem called gemcutter is available? Is this managing gems for us but in RubyGems.org now?

Grateful if someone could enlighten me on this topic.

Are there any reasons for hosting my gems on GitHub and not RubyGems?

1) GitHub has stopped building new gems, but is continuing to host gems that were previously placed on the site.) The answer is, you can't. (

The GitHub gem building process was always kind of hacky and wasn't 100% solid. (check out the "gem issues" support queue on their help site sometime). GitHub's about git hosting, Gemcutter is about gem hosting. Enough said. :)

Does RubyGems have private repositories like GitHub?

Nope, not yet. We've considered it, but offering private gem servers/subdomains seems to conflict with the open nature of the site. If you need a gem server for your code that is internal, just use gem server or geminabox.

I've read that jeweler is nice for creating gem skeleton. On their webpage it sounds like it uploads these gems to GitHub and not RubyGems. But didn't GitHub removed the Gem support?

Jeweler's still a great way to get started creating a gem. I'm pretty sure rake release with Jeweler's rake tasks installed will just do a gem push now, so it will publish to RubyGems.org.

This railscast http://media.railscasts.com/videos/183_gemcutter_and_jeweler.mov shows us how to use gemcutter to manage gems. But Gemcutter.org is now RubyGems.org right? But still a gem called gemcutter is available? Is this managing gems for us but in RubyGems.org now?

Yep, gemcutter.org, rubygems.org, and gems.rubyforge.org all redirect to the same place. The gem push and gem owner commands are now in RubyGems proper, so you don't need the gemcutter gem to publish anymore. The gemcutter gem is still available and contains yet to be merged in commands, such as gem yank and gem webhook.

The full story on all of the transition changes is here.

What does == do in Ruby?

9 votes

In Java, == is the strongest kind of equality (pointer equality): a == b always implies a.equals(b). However, in Ruby, == is weaker than .equals?:

ruby-1.9.2-rc2 > 17 == 17.0
 => true 
ruby-1.9.2-rc2 > 17.equal?(17.0)
 => false

So, where can I learn more about ==? What kind of checks should I expect when I compare two objects with it?

briefly this is what you need to know:

The == comparison checks whether two values are equal

eql? checks if two values are equal and of the same type

equal? checks if two things are one and the same object.

A good blog about this is here.

Should I use Ruby 1.9.2 with my new web app?

9 votes

Starting a new web app with Rails 3. I'm still relatively new to web development and have really enjoyed all the internet resources available to me while working in Ruby 1.8.7 and Rails 2.3.5. Any advice against using Ruby 1.9.2 on my new project?

I have been successfully converting all my Rails projects (except one, but I'm working on it) from Ruby 1.8.7/Rails 2.3.5 to Rails 3.0.0 and Ruby 1.8.7/1.9.2 RC2 and both environments are pretty stable.

Fortunately, things changed since I posted this question.

Rails

Unless you really have something that prevents you to do that, I strongly encourage you to start with Rails 3. The effort required to upgrade an application from Rails 2 to Rails 3 should discourage you from starting from Rails 2.

Talking about plugins and Gems, many developers are starting to convert their libraries to Rails 3. Currently there's a very high level of compatibility. Furthermore, Rails 3 focused plugins tends to be quite more powerful to the Rails 2.3 ones, thanks to the new Rails plugin API. They can load tasks, they no longer abuse monkey patching or rely on internal hacks.

Also, Rails 3 is just around the corner. Unless your project will be deployed in 1 week, the stable version will probably available before you deploy your code. I this would not happe, consider that I'm currently managing a couple of Rails 3 project in a production environment and they are pretty stable (Rails 3 RC1, the Beta 4 has a really weird bug in the caching environment).

Ruby 1.9.2

Ruby 1.9.2 is way more powerful than Ruby 1.8.7. If this is a brand new project, I suggest you to use the 1.9 branch.

Usually, it's more easy to start a new project in Ruby 1.9 than converting an existing one.

Ruby 1.9.2 is faster, even more faster than REE. The most part of the common Ruby 1.8.7 Gems work with Ruby 1.9 except a few ones, such as RCov. Again, it's very hard you're going to need a library which doesn't work with Ruby 1.9.2.

If it happens, chances are this is an outdated library and a better replacement is probably available in the Ruby ecosystem.

If you can't find an alternative, remember that Rails 3 provides an excellent way to use custom libraries, thanks to Bundler. You can fork the project and ask Bundler to use your fork. You can even integrate the library in your repos and ask Bundler to load the library from a path.

Conclusion

From my personal experience, I've been very happy with Ruby 1.9.2 and Rails 3. This is by far my favorite environment and my default environment for new projects.

If you can't use Ruby 1.9.2 try with Ruby 1.8.7. On the other side, I strongly encourage you to start with Rails 3.

What vulnerabilities are possible in ruby with $SAFE >= 1?

8 votes

Ruby's safe mode disallows the use of tainted data by potentially dangerous operations. It varies in levels, 0 being disabled, and then 1-4 for levels of security. What vulnerabilities are possible when safe mode is enabled? Do you know of any CVE numbers issued to a ruby program when safe mode is enabled? What CWE Violations (or cwe families) are possible with safe mode enabled?

All application-level vulnerabilities are completely unaffected by the $SAFE level. Injection attacks that don't pass through an "unsafe operation" like cross-site scripting and SQL injection for example. This includes, more or less, every vulnerability class for web applications, except perhaps local and remote file inclusion. See the OWASP Top 10, $SAFE doesn't help with many of these.

The $SAFE level does protect you somewhat against system-level vulnerabilities though. If an attacker is able to write Ruby code into a file in /tmp, they wouldn't then be able to trick your program into loading that code if $SAFE >= 2.

And this of course doesn't include any vulnerabilities with Ruby itself. These are much more serious, and can bypass $SAFE entirely.

Or plain old buffer overflows, integer overflows, etc in the Ruby interpreter itself that have nothing to do with $SAFE.

Rails has a history vulnerabilities that occur whether $SAFE is enabled or not. This is complicated by the fact that user input is stored in Rails applications, and malicious data can pop back up at a later time.

Vulnerability reports in Ruby applications other than Rails and MRI are hard to come by.

Another big problem with $SAFE is there is no real list (that I know of) that outlines exactly what $SAFE does and doesn't protect. About the only thing you can do is search for *ruby_safe_level* in eval.c (this is an older eval.c from 1.8.4). The comments provide this description, but it's pretty vague.

/* safe-level:
   0 - strings from streams/environment/ARGV are tainted (default)
   1 - no dangerous operation by tainted value
   2 - process/file operations prohibited
   3 - all generated objects are tainted
   4 - no global (non-tainted) variable modification/no direct output
*/

I guess what I'm trying to say is that $SAFE is all about system security. It does an OK job, but there's no real way to know exactly what is and is not protected. It shouldn't be your only line of defense, it's more of a safety net so nothing slips through to an "unsafe operation." On the other hand, it has nothing to do with application security, and won't save your data or users from being compromised. And on top of that, MRI has a history of vulnerabilities that bypass $SAFE entirely.

Ruby - determining method origins?

7 votes

When sent a message, a Ruby object searches to see whether it has a method by that name to respond with. Its method lookup searches in the following order, and uses the first method it finds.

  1. Singleton methods defined on itself
  2. Methods defined in its class
  3. Any modules mixed into its class, in reverse order of inclusion (only the earliest inclusion of a given module has any effect - if the superclass includes module A, and the subclass includes it again, it’s ignored in the subclass; if the subclass includes A then B then A, the second A is ignored)
  4. Its superclass
  5. Any methods mixed into the superclass, and so on up the line

This lookup path is followed at the moment the method is called; if you make an instance of a class, then reopen the class and add a method or mix one in via a module, the existing instance will gain access to that method.

If all of this fails, it looks to see if it has a method_missing method, or if its class does, etc.

My question is this: aside from examining the code by hand, or using example methods like puts "I'm on module A!", can you tell where a given method came from? Can you, for example, list an object's methods and see "this one is on the superclass, this one is on module A, this one is on the class and overrides the superclass," etc?

Object#method returns a Method object giving meta-data about a given method. For example:

> [].method(:length).inspect
=> "#<Method: Array#length>"
> [].method(:max).inspect
=> "#<Method: Array(Enumerable)#max>"

In Ruby 1.8.7 and later, you can use Method#owner to determine the class or module that defined the method.

To get a list of all the methods with the name of the class or module where they are defined you could do something like the following:

obj.methods.collect {|m| "#{m} defined by #{obj.method(m).owner}"}

Puzzled over palindromic product problem

6 votes

I've been learning Ruby, so I thought I'd try my hand at some of the project Euler puzzles. Embarrassingly, I only made it to problem 4...

Problem 4 goes as follows:

A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.

Find the largest palindrome made from the product of two 3-digit numbers.

So I figured I would loop down from 999 to 100 in a nested for loop and do a test for the palindrome and then break out of the loops when I found the first one (which should be the largest one):

final=nil
range = 100...1000
for a in range.to_a.reverse do
  for b in range.to_a.reverse do
    c=a*b
    final=c if c.to_s == c.to_s.reverse
    break if !final.nil?
  end
  break if !final.nil?
end
puts final

This does output a palindrome 580085, but apparently this isn't the highest product of two three-digit numbers within the range. Strangely, the same code succeeds to return 9009, like in the example, if I change the range to 10...100.

  • Can someone tell me where I am going wrong?
  • Also, is there a nicer way to break out of the internal loop?

Thanks

You are testing 999* (999...100), then 998 * (999...100)

Hence you will be testing 999 * 500 before you test 997 * 996.

So, how you we find that right number?

First note the multiplication is reflective, a * b == b * a, so b need not go from 999...0 every time, just a ...0.

When you find a palindrone, add the two factors together and save the sum (save the two factors also)

Inside the loop, if (a+b) is ever less than the saved sum, abandon the inner loop and move to the next a. When a falls below sum/2, no future value you could find would be higher than the one you've already found, so you're done.

Ruby - pick randomly from an array

6 votes

I want to know if there is a much cleaner way of doing this. Basically, I want to pick a random element from an array of variable length. Normally, I would do it like this:

myArray = ["stuff", "widget", "ruby", "goodies", "java", "emerald", "etc" ]
item = myArray[rand(myarray.length)]

Is there something that is more readable / simpler to replace the second line? Or is that the best way to do it. I suppose you could do myArray.shuffle.first, but I only saw #shuffle a few minutes ago on SO, I haven't actually used it yet.

Thanks!

Just use Array#sample:

[:foo, :bar].sample # => :foo, or :bar :-)

It is available in Ruby 1.9, so if using an earlier version, require "backports". Note that in Ruby 1.8.7 it exists under the unfortunate name choice; it was renamed in later version so you shouldn't use it.

Rake vs Thor for automation scripts?

6 votes

I want to automate things like:

  • Creating a new Rails app with pre-selected database, git initialize it, create heroku project, commit all files etc

  • Upload all files in folder to another computer through ssh, but do not overwrite files

  • Upgrade Ubuntu, install all basic packages through apt-get

These kind of tasks.

From what I have understood, tools for this are Rake and Thor.

However, which one should I use?

Rake seems to me more de-facto and popular. I have heard people recommending Thor.

How do these stand to each other in a rundown?

Rake and Thor serve different purposes.

Rake is a general build script tool that is project-specific. In other words, you put your rakefile your project folder and in your project's source control, and you create build and other automation tasks that are specific to your project in that rakefile. rake requires a rakefile to run.

Thor is a general purpose command line scripting tool that makes it very easy to re-use scripts across many projects and to do project setup, etc. like you are suggesting. Thor allows you to "install" an executable script that you can call from anywhere on your system, similar to calling "ruby", "gem" or "rake" command lines. However, thor's scripts are more suited to general purpose, cross-application automation because the thor script does not rely on a file sitting in your project specific folder. a Thor script is the entire script, packed and installed for re-use anywhere.

Based on your stated needs, you are better off using Thor because you will be able to install your script in one location and have it work anywhere on your system. you will not be bound to a rakefile sitting or anything like that.

...

by the way: Rails 3 uses Thor for pretty much everything that is not project specific. you still have a rakefile and you still run things like "rake db:migrate" or "rake test:units". Thor is used for things like "rails new ...", "rails server" and "rails generate ..." The use of Thor AND Rake in rails 3 is the perfect illustration of where each of these tools is best suited.

Is there a supplementary guide/answer key for ruby koans?

6 votes

I have recently tried sharping my rails skills with this tool:

http://github.com/edgecase/ruby_koans

but I am having trouble passing some tests. Also I am not sure if I'm doing some things correctly since the objective is to just pass the test, there are a lot of ways in passing it and I may be doing something that isn't up to standards.

Is there a way to confirm if I'm doing things right?

a specific example:

in about_nil,

 def test_nil_is_an_object
   assert_equal __, nil.is_a?(Object), "Unlike NULL in other languages"
 end

so is it telling me to check if that second clause is equal to an object(so i can say nil is an object) or just put assert_equal true, nil.is_a?(Object) because the statement is true?

and the next test:

def test_you_dont_get_null_pointer_errors_when_calling_methods_on_nil
  # What happens when you call a method that doesn't exist.  The
  # following begin/rescue/end code block captures the exception and
  # make some assertions about it.
  begin
    nil.some_method_nil_doesnt_know_about
  rescue Exception => ex
    # What exception has been caught?
    assert_equal __, ex.class

    # What message was attached to the exception?
    # (HINT: replace __ with part of the error message.)
    assert_match(/__/, ex.message)
  end
end

Im guessing I should put a "No method error" string in the assert_match, but what about the assert_equal?

assert_equal true, nil.is_a?(Object) is indeed the correct solution. The question is "Are nils in Ruby objects or not?", and in Ruby's case, they are. Thus, in order to pass the assertion, you should assert the truth of that test.

In the second example, when you call an undefined method on nil, you get NoMethodError: undefined method 'foo' for nil:NilClass. Thus, the exception class is NoMethodError, and the message is undefined method 'foo' for nil:NilClass. Test the failing behavior in a console, and see what you get from it, and then apply that knowledge to the test.