Best ruby questions in December 2010

Count, size, length...too many choices in Ruby?

14 votes

I can't seem to find a definitive answer on this and I want to make sure I understand this to the "n'th level" :-)

a = { "a" => "Hello", "b" => "World" }
a.count  # 2
a.size   # 2
a.length # 2

a = [ 10, 20 ]
a.count  # 2
a.size   # 2
a.length # 2

So which to use? If I want to know if a has more than one element then it doesn't seem to matter but I want to make sure I understand the real difference. This applies to arrays too. I get the same results.

Also, I realize that count/size/length have different meanings with ActiveRecord. I'm mostly interested in pure Ruby (1.92) right now but if anyone wants to chime in on the difference AR makes that would be appreciated as well.

Thanks!

For arrays and hashes size is an alias for length. They are synonyms and do exactly the same thing.

count is more versatile - it can take an element or predicate and count only those items that match.

> [1,2,3].count{|x| x > 2 }
=> 1

In the case where you don't provide a parameter to count it has basically the same effect as calling length. There can be a performance difference though.

We can see from the source code for Array that they do almost exactly the same thing. Here is the C code for the implementation of array.length:

static VALUE
rb_ary_length(VALUE ary)
{
    long len = RARRAY_LEN(ary);
    return LONG2NUM(len);
}

And here is the relevant part from the implementation of array.count:

static VALUE
rb_ary_count(int argc, VALUE *argv, VALUE ary)
{
    long n = 0;

    if (argc == 0) {
        VALUE *p, *pend;

        if (!rb_block_given_p())
            return LONG2NUM(RARRAY_LEN(ary));

        // etc..
    }
}

The code for array.count does a few extra checks but in the end calls the exact same code: LONG2NUM(RARRAY_LEN(ary)).

Hashes (source code) on the other hand don't seem to implement their own optimized version of count so the implementation from Enumerable (source code) is used, which iterates over all the elements and counts them one-by-one.

In general I'd advise using length (or its alias size) rather than count if you want to know how many elements there are altogether.


Regarding ActiveRecord, check out this post:

Learn Ruby Without Poignancy

13 votes

I suppose this is two very closely related questions:

  • Everyone says to start with Why's (Poignant) Guide to Ruby, and I can't stand that book; what's another good starting point for an experienced programmer that has a more serious tone?
  • If I'm not the sort of person who appreciates _why, should I skip Ruby because the community will not be to my taste?

I'm currently rolling through Programming Ruby: The Pragmatic Programmer's Guide. So far I think the concepts are well-defined by the authors, and the examples provided help clarify any misunderstandings. The book is available for free online or you can order a copy:

http://www.ruby-doc.org/docs/ProgrammingRuby/

Update: More current version of book (Thanks bgporter)

http://pragprog.com/titles/ruby3/programming-ruby-1-9

The only problem with the online version is that it is a little outdated. I don't know Ruby that well yet so I can't say how much of the book is still valid in all cases, but the examples have worked for me so far when I run them. Note that the book available for purchase is up to date. It's hard to beat free, so be sure to check this guide out.

That being said, I don't think you should skip out on Ruby just yet. I've had a blast learning the language so far, and I'm looking forward to doing some full-fledged web development with Rails soon. At the very least give the language a chance; I think you'll find it a joy to work with.

Why doesn't Rails' "errors.full_messages" replace attribute and message variables?

13 votes

Having a strange problem with a rails model I just created.

Here are my validations:

validates_presence_of :from_name, :message => 'Please provide a from name.'
validates_presence_of :from_email
validates_presence_of :giftition_plan_id

I'm having issues using errors.full_messages as well as f.error_messages in my form:

g = Giftition.create
g.errors.first
=> ["from_name", "Please provide a from name."]
>> g.errors.full_messages
=> ["{{attribute}} {{message}}", "{{attribute}} {{message}}", "{{attribute}} {{message}}"]

I'm just getting "{{attribute}} {{message}}". Any ideas?

UPDATE: I've uninstalled rails 3 and all the gems that were installed with it and that made the problem go away. It's not a fix though... I would still like to have rails 3 installed.

UPDATE: Sounds like upgrading to 2.3.9 fixes the problem. Unfortunately, I've given up for now, but sometime in the future I will try that.

Upgrading to Version rails 2.3.9 fixes this problem

gem install -v 2.3.9 rails --include-dependencies

EDIT:

You also need to edit the config\environment.rb file to change the RAILS_GEM_VERSION.

RAILS_GEM_VERSION = '2.3.9'

EDIT #2:

I should note that version 2.3.9 is not the latest version of the 2.3.X branch, and you should upgrade the the latest version available.

Is Ruby's code block same as C#'s lambda expression?

12 votes

Are these two essentially the same thing? They look very similar to me.

Did lambda expression borrow its idea from Ruby?

Ruby actually has 4 constructs that are all extremely similar

The Block

The idea behind blocks is sort of a way to implement really light weight strategy patterns. A block will define a coroutine on the function, which the function can delegate control to with the yield keyword. We use blocks for just about everything in ruby, including pretty much all the looping constructs or anywhere you would use using in c#. Anything outside the block is in scope for the block, however the inverse is not true, with the exception that return inside the block will return the outer scope. They look like this

def foo
  yield 'called foo'
end

#usage
foo {|msg| puts msg} #idiomatic for one liners

foo do |msg| #idiomatic for multiline blocks
  puts msg
end

Proc

A proc is basically taking a block and passing it around as a parameter. One extremely interesting use of this is that you can pass a proc in as a replacement for a block in another method. Ruby has a special character for proc coercion which is &, and a special rule that if the last param in a method signature starts with an &, it will be a proc representation of the block for the method call. Finally, there is a builtin method called block_given?, which will return true if the current method has a block defined. It looks like this

def foo(&block)
  return block
end

b = foo {puts 'hi'}
b.call # hi

To go a little deeper with this, there is a really neat trick that rails added to Symbol (and got merged into core ruby in 1.9). Basically, that & coercion does its magic by calling to_proc on whatever it is next to. So the rails guys added a Symbol#to_proc that would call itself on whatever is passed in. That lets you write some really terse code for any aggregation style function that is just calling a method on every object in a list

class Foo
  def bar
    'this is from bar'
  end
end

list = [Foo.new, Foo.new, Foo.new]

list.map {|foo| foo.bar} # returns ['this is from bar', 'this is from bar', 'this is from bar']
list.map &:bar # returns _exactly_ the same thing

More advanced stuff, but imo that really illustrates the sort of magic you can do with procs

Lambdas

The purpose of a lambda is pretty much the same in ruby as it is in c#, a way to create an inline function to either pass around, or use internally. Like blocks and procs, lambdas are closures, but unlike the first two it enforces arity, and return from a lambda exits the lambda, not the containing scope. You create one by passing a block to the lambda method, or to -> in ruby 1.9

l = lambda {|msg| puts msg} #ruby 1.8
l = -> {|msg| puts msg} #ruby 1.9

l.call('foo') # => foo

Methods

Only serious ruby geeks really understand this one :) A method is a way to turn an existing function into something you can put in a variable. You get a method by calling the method function, and passing in a symbol as the method name. You can re bind a method, or you can coerce it into a proc if you want to show off. A way to re-write the previous method would be

l = lambda &method(:puts)
l.call('foo')

What is happening here is that you are creating a method for puts, coercing it into a proc, passing that in as a replacement for a block for the lambda method, which in turn returns you the lambda


Feel free to ask about anything that isn't clear (writing this really late on a weeknight without an irb, hopefully it isn't pure gibberish)

EDIT: To address questions in the comments

list.map &:bar Can I use this syntax with a code block that takes more than one argument? Say I have hash = { 0 => "hello", 1 => "world" }, and I want to select the elements that has 0 as the key. Maybe not a good example. – Bryan Shen

Gonna go kind of deep here, but to really understand how it works you need to understand how ruby method calls work.

Basically, ruby doesn't have a concept of invoking a method, what happens is that objects pass messages to each other. The obj.method arg syntax you use is really just sugar around the more explicit form, which is obj.send :method, arg, and is functionally equivalent to the first syntax. This is a fundamental concept in the language, and is why things like method_missing and respond_to? make sense, in the first case you are just handling an unrecognized message, the second you are checking to see if it is listening for that message.

The other thing to know is the rather esoteric "splat" operator, *. Depending on where its used, it actually does very different things.

def foo(bar, *baz)

In a method call, if it is the last parameter, splat will make that parameter glob up all additional parameters passed in to the function (sort of like params in C#)

obj.foo(bar, *[biz, baz])

When in a method call (or anything else that takes argument lists), it will turn an array into a bare argument list. The snippet below is equivilent to the snippet above.

obj.foo(bar, biz, baz)

Now, with send and * in mind, Symbol#to_proc is basically implemented like this

class Symbol
  def to_proc
    Proc.new { |obj, *args| obj.send(self, *args) }
  end
end

So, &:sym is going to make a new proc, that calls .send :sym on the first argument passed to it. If any additional args are passed, they are globbed up into an array called args, and then splatted into the send method call.

I notice that & is used in three places: def foo(&block), list.map &:bar, and l = lambda &method(:puts). Do they share the same meaning? – Bryan Shen

Yes, they do. An & will call to_proc on what ever it is beside. In the case of the method definition it has a special meaning when on the last parameter, where you are pulling in the co-routine defined as a block, and turning that into a proc. Method definitions are actually one of the most complex parts of the language, there are a huge amount of tricks and special meanings that can be in the parameters, and the placement of the parameters.

b = {0 => "df", 1 => "kl"} p b.select {|key, value| key.zero? } I tried to transform this to p b.select &:zero?, but it failed. I guess that's because the number of parameters for the code block is two, but &:zero? can only take one param. Is there any way I can do that? – Bryan Shen

This should be addressed earlier, unfortunately you can't do it with this trick.

"A method is a way to turn an existing function into something you can put in a variable." why is l = method(:puts) not sufficient? What does lambda & mean in this context? – Bryan Shen

That example was exceptionally contrived, I just wanted to show equivalent code to the example before it, where I was passing a proc to the lambda method. I will take some time later and re-write that bit, but you are correct, method(:puts) is totally sufficient. What I was trying to show is that you can use &method(:puts) anywhere that would take a block. A better example would be this

['hello', 'world'].each &method(:puts) # => hello\nworld

l = -> {|msg| puts msg} #ruby 1.9: this doesn't work for me. After I checked Jörg's answer, I think it should be l = -> (msg) {puts msg}. Or maybe i'm using an incorrect version of Ruby? Mine is ruby 1.9.1p738 – Bryan Shen

Like I said in the post, I didn't have an irb available when I was writing the answer, and you are right, I goofed that (spend the vast majority of my time in 1.8.7, so I am not used to the new syntax yet)

There is no space between the stabby bit and the parens. Try l = ->(msg) {puts msg}. There was actually a lot of resistance to this syntax, since it is so different from everything else in the language.

Please recommend me some rails/ruby open source code that needs documentation/tests written

11 votes

I've been using ruby on rails for the last 4 months or so and I've been really enjoying the whole concept of open source. I know it's not exclusive to ruby/rails but coming from windows programming this is my first real exposure to it.

I want to "give back" what I can but I don't feel like I can contribute any worthwhile open source projects or gems of my own. So I figured a good place to start is by documenting or writing tests for some existing projects.

Could you guys please point me to a few possible options? I'd prefer projects that are pretty active but at the same time not too complex (since I'm not very good with ruby right now).

This might be a subjective question but at this point I have no idea where to even start. So even subjective answers would be much appreciated.

Kudos! There are several ways to participate.

I think the question to ask yourself is, what are your areas of expertise? What subject area to you have a solid knowledge of? For example, if you had experience with Web Services, the Savon project is in dire need of documentation, examples, etc. If you have Java experience, there are many burgeoning JRuby projects that could use a hand.

You can check the Ruby Toolbox, which lists gems in categories by popularity. Look in the areas that appeal to you and check out the popular gems. The vast majority of gems have github repositories. If you haven't learned git, I highly recommend it. It's super easy to branch a project, update it. Look for projects which have a good test suite, which will not only help you figure out how it works, but will give you good examples for testing your additions/fixes.

Also, the Ruby and Rails documentation at APIdock allows for comments. If you come across something that's not entirely clear in the Rails documentation, for example, you can add a clarifying comment or examples.

Algorithms to efficiently "scale" or "resize" of an array of numbers (audio resampling)

10 votes

Doing audio processing (though it could just as well be image processing) I have a one-dimensional array of numbers. (They happen to be 16-bit signed integers representing audio samples, this question could apply to floats or integers of different sizes equally.)

In order to match audio with different frequencies (e.g. blend a 44.1kHz sample with a 22kHz sample), I need to either stretch or squash the array of values to meet a specific length.

Halving the array is simple: drop every other sample.

[231, 8143, 16341, 2000, -9352, ...] => [231, 16341, -9352, ...]

Doubling the array width is slightly less simple: double each entry in place (or optionally perform some interpolation between neighboring 'real' samples).

[231, 8143, 16341, 2000, -9352, ...] => [231, 4187, 8143, 12242, 16341, ...]

What I want is an efficient, simple algorithm that handles any scaling factor, and (ideally) optionally supports performing interpolation of one kind or another in the process.

My use case happens to be using Ruby arrays, but I'll happily take answers in most any language or pseudo-code.

This is something I threw together in a few minutes just as I was leaving work, then recreated after a glass of wine after dinner:

sample = [231, 8143, 16341, 2000, -9352]
new_sample = []
sample.zip([] * sample.size).each_cons(2) do |a,b|
  a[1] = (a[0] + b[0]).to_f / 2 # <-- simple average could be replaced with something smarter
  new_sample << a
end
new_sample.flatten!
new_sample[-1] = new_sample[-2]
new_sample # => [231, 4187.0, 8143, 12242.0, 16341, 9170.5, 2000, 2000]

I think it's a start but obviously not finished since the -9352 didn't propagate into the final array. I didn't bother converting floats to ints; I figure you know how to do that. :-)

I'd like to find a better way to iterate over each_cons. I'd rather use a map than each* but this works OK.

Here's what the loop iterates over:

asdf = sample.zip([] * sample.size).each_cons(2).to_a 
asdf # => [[[231, nil], [8143, nil]], [[8143, nil], [16341, nil]], [[16341, nil], [2000, nil]], [[2000, nil], [-9352, nil]]]

each_cons is nice because it steps through the array returning slices of it, which seemed like a useful way to build up the averages.

[0,1,2,3].each_cons(2).to_a # => [[0, 1], [1, 2], [2, 3]]

EDIT:

I like this better:

sample = [231, 8143, 16341, 2000, -9352]

samples = sample.zip([] * sample.size).each_cons(2).to_a 
new_sample = samples.map { |a,b|
  a[1] = (a[0] + b[0]).to_f / 2
  a
}.flatten
new_sample << sample[-1]
new_sample # => [231, 4187.0, 8143, 12242.0, 16341, 9170.5, 2000, -3676.0, -9352]

Turn omniauth facebook login into a popup

9 votes

I'm using the omniauth gem with rails and it works great with loging in users, but everytime it takes you to the fb login page then redirects you back. I was wondering if there is a way to do what most pages do and show the fb login in a popup and then reload the parent div once that is complete. Any ideas?

Thanks!

Sure, you can easily.

In your view:

=link_to "Log in with Facebook", omniauth_authorize_path(:user, :facebook), :class => "popup", :"data-width" => 600, :"data-height" => 400

In your application.js:

function popupCenter(url, width, height, name) {
  var left = (screen.width/2)-(width/2);
  var top = (screen.height/2)-(height/2);
  return window.open(url, name, "menubar=no,toolbar=no,status=no,width="+width+",height="+height+",toolbar=no,left="+left+",top="+top);
}

$("a.popup").click(function(e) {
  popupCenter($(this).attr("href"), $(this).attr("data-width"), $(this).attr("data-height"), "authPopup");
  e.stopPropagation(); return false;
});

And then in your callback view:

:javascript
  if(window.opener) {
    window.opener.location.reload(true);
    window.close()
  }

This'll pop up your Facebook auth in a centered 600x400 popup, then when the user returns from authentication, the view will close the popup and refresh the parent page. It degrades gracefully if a user ctrl-clicks the link, or doesn't have Javascript enabled, too.

Do ruby on rails programmers refactor?

9 votes

I'm a Java programmer who started programming Ruby on Rails one year ago. I like the language, rails itself and the principles behind them. But something that bothers me is that Ruby programmers don't seem to refactor.

I noticed that there is a big lack of tools for refactoring in Ruby / Rails. Some IDE's, like Aptana and RubyMine seem to offer some very basic refactoring, but nothing really big compared to Eclipse's Java refactorings.

Then there is another fact: most railers (even the pros) prefer some lightweight editors, like VIM or TextMate, instead of IDEs. Well, with these tools you just get zero refactoring (only regex with find/replace).

This leaves me this impression that rails programmers don't refactor. It might be just a false impression, of course, but I would like to hear the opinion of people who work professionally with ruby on rails.

Do you refactor? If you do, how do you do it,with which tools? If not, why not?

Yes.

Most Rails programmers try and follow a Test first, write code to pass the test, then refactor the code BEFORE they go onto the next test.

Do ALL rails/ruby programmers... probably not, but as far as a 'vibe' or 'feel' in this community, I'd say it's something that is preached and practiced enough that it happens more times than not.

There is no need for IDEs imo. VIM, emacs and/or textmate is enough for Ruby and most rails programmers. I guess Java needed more compiling or something, what do I know about that though, as I've only programmed in Ruby. Why do all Java programmers use IDEs (since I'm generalizing).

what is the point of heterogenous arrays?

9 votes

I know that more-dynamic-than-Java languages, like Python and Ruby, often allow you to place objects of mixed types in arrays, like so:

["hello", 120, ["world"]]

What I don't understand is why you would ever use a feature like this. If I want to store heterogenous data in Java, I'll usually create an object for it.

For example, say a User has int ID and String name. While I see that in Python/Ruby/PHP you could do something like this:

[["John Smith", 000], ["Smith John", 001], ...]

this seems a bit less safe/OO than creating a class User with attributes ID and name and then having your array:

[<User: name="John Smith", id=000>, <User: name="Smith John", id=001>, ...]

where those <User ...> things represent User objects.

Is there reason to use the former over the latter in languages that support it? Or is there some bigger reason to use heterogenous arrays?

N.B. I am not talking about arrays that include different objects that all implement the same interface or inherit from the same parent, e.g.:

class Square extends Shape
class Triangle extends Shape
[new Square(), new Triangle()]

because that is, to the programmer at least, still a homogenous array as you'll be doing the same thing with each shape (e.g., calling the draw() method), only the methods commonly defined between the two.

As katrielalex wrote: There is no reason not to support heterogeneous lists. In fact, disallowing it would require static typing, and we're back to that old debate. But let's refrain from doing so and instead answer the "why would you use that" part...

To be honest, it is not used that much -- if we make use of the exception in your last paragraph and choose a more liberal definition of "implement the same interface" than e.g. Java or C#. Nearly all of my iterable-crunching code expects all items to implement some interface. Of course it does, otheriwise it could do very little to it!

Don't get me wrong, there are absolutely valid use cases - there's rarely a good reason to write a whole class for containing some data (and even if you add some callables, functional programming sometimes comes to the rescue). A dict would be a more common choice though, and namedtuple is very neat as well. But they are less common than you seem to think, and they are used with thought and discipline, not for cowboy coding.

(Also, you "User as nested list" example is not a good one - since the inner lists are fixed-sized, you better use tuples and that makes it valid even in Haskell (type would be [(String, Integer)]))

Storing user-generated text in database securely (Ruby/Rails)

8 votes

I'm trying to figure out a way to store user-generated text securely in a database (so that only the user is the one who can access his/her stored text). I could have Rails encrypt and decrypt the user's text entries using the user's password as the key, but if the user ever forgot their password there would be no way to ever decrypt their previous content/text (since the Rails app uses BCrypt to store only a hash of the password).

Does anyone know how that could be done? It looks like Dropbox does something like it: "All files stored on Dropbox servers are encrypted (AES-256) and are inaccessible without your account password." (http://www.dropbox.com/help/27) Yet they allow you to reset your password and I'm assuming they don't store your plain text password anywhere.

What am I missing? Any suggestions would be greatly appreciated. Thanks!

Build on Gintautas' Option 1 with a two-prong encryption plan:

  1. Apply option 1, with a key that is known to the server, and
  2. Store the database on disk in an encrypted format with a key that is known only to the server. E.g., in an encrypted volume. When the server starts up, the key must be manually entered in order to access the database.

This "static security" provided by part 2 protects against an intruder in the system gaining access to the database files. Maybe not 100% the exact security you're after, but getting closer.

Symbol to string issue

7 votes

Following code fails

world = :world
result = 'hello' + world
puts result #=> can't convert Symbol into String

Following code works

world = :world
result = "hello #{world}"
puts result #=> hello world

Why?

Using ruby 1.8.7

String interpolation is an implicit to_s call. So, something like this:

result = "hello #{expr}"

is more or less equivalent to this:

result = "hello " + expr.to_s

As karim79 said, a symbol is not a string but symbols do have to_s methods so your interpolation works; your attempt at using + for concatenation doesn't work because there is no implementation of + available that understand a string on the left side and a symbol on the right.

Fastest reliable way for Clojure (Java) and Ruby apps to communicate

7 votes

Hi There,

We have cloud-hosted (RackSpace cloud) Ruby and Java apps that will interact as follows:

  1. Ruby app sends a request to Java app. Request consists of map structure containing strings, integers, other maps, and lists (analogous to JSON).
  2. Java app analyzes data and sends reply to Ruby App.

We are interested in evaluating both messaging formats (JSON, Buffer Protocols, Thrift, etc.) as well as message transmission channels/techniques (sockets, message queues, RPC, REST, SOAP, etc.)

Our criteria:

  1. Short round-trip time.
  2. Low round-trip-time standard deviation. (We understand that garbage collection pauses and network usage spikes can affect this value).
  3. High availability.
  4. Scalability (we may want to have multiple instances of Ruby and Java app exchanging point-to-point messages in the future).
  5. Ease of debugging and profiling.
  6. Good documentation and community support.
  7. Bonus points for Clojure support.
  8. Good dynamic language support.

What combination of message format and transmission method would you recommend? Why?

I've gathered here some materials we have already collected for review:

We have decided to go with BSON over RabbitMQ.

We like BSON's support for heterogeneous collections and the lack of the need to specify the format of messages up-front. We don't mind that it has poor space usage characteristics and likely poorer serialization performance than other message formats since the messaging portion of our application is not anticipated to be the bottleneck. It doesn't look like a nice Clojure interface has been written to let you directly manipulate BSON objects, but hopefully that won't be an issue. I will revise this entry if we decide that BSON won't work out for us.

We chose RabbitMQ mainly because we already have experience with it and are using it in a system that demands high throughput and availability.

If messaging does become a bottleneck, we will look first to BERT (we rejected it because it currently does not appear to have Java support), then to MessagePack (rejected because it appears that there isn't a large community of Java developers using it), then to Avro (rejected because it requires you to define your message format up-front), then Protocol Buffers (rejected because of the extra code generation step and lack of heterogeneous collections) and then Thrift (rejected for the reasons mentioned for Protocol Buffers).

We may want to go with a plain RPC scheme rather than using a message queue since our messaging style is essentially synchronous point-to-point.

Thanks for your input everyone!

Update: Here is the project.clj and core.clj that shows how to convert Clojure maps to BSON and back:

;;;; project.clj

(defproject bson-demo "0.0.1"
  :description "BSON Demo"
  :dependencies [[org.clojure/clojure "1.2.0"]
                 [org.clojure/clojure-contrib "1.2.0"]
                 [org.mongodb/mongo-java-driver "2.1"]]
  :dev-dependencies [[swank-clojure "1.3.0-SNAPSHOT"]]
  :main core)

;;;; core.clj
(ns core
  (:gen-class)
  (:import [org.bson BasicBSONObject BSONEncoder BSONDecoder]))

(defonce *encoder* (BSONEncoder.))

(defonce *decoder* (BSONDecoder.))

;; XXX Does not accept keyword arguments. Convert clojure.lang.Keyword in map to java.lang.String first.
(defn map-to-bson [m]
  (->> m (BasicBSONObject.) (.encode *encoder*)))

(defn bson-to-map [^BasicBSONObject b]
  (->> (.readObject *decoder* b) (.toMap) (into {})))

(defn -main []
  (let [m {"foo" "bar"}]
    (prn (bson-to-map (map-to-bson m)))))

What is the right way to initialize a constant in Ruby?

7 votes

I have a simple class that defines some constants, e.g.:

module Foo
  class Bar
    BAZ = "bof"
    ...

Everything is puppies and rainbows until I tell Rake to run all my Test::Unit tests. When it does, I get warnings:

bar.rb:3: warning: already initialized constant BAZ

My habit has been to avoid these warnings by making the constant initialization conditional, e.g.:

...
BAZ = "bof" unless const_defined? :BAZ
...

This seems to solve the problem, but it is a little tedious, and I don't ever see anyone else initializing constants this way. This makes me think I might be Doing It Wrong. Is there a better way to initialize constants that won't generate warnings?

Update: By way of a little more detail on how I'm using these constants, let's say I've defined a Token class that has constants for all the characters that are part of the syntax of some artificial language. I also have a Scanner class that reads a stream of characters, generating a Token instance for each one.

module Foo
  class Token
    LPAREN = "("
    RPAREN = ")"
    ...
  end

  class Scanner
    def next_token
      case read_char()
        when Token::LPAREN: # Generate a new LPAREN token
        ...

That is, when checking to see what kind of token should be generated for the given character, I want to use the constants defined in Token.

Update 2: Jörg's answer revealed that the problem was probably in how I was constructing paths in my require statements, not in how I was initializing or using the constants. I rewrote my require statements to eliminate any manual path creation, e.g.:

# File: $PROJECT_ROOT/lib/foo.rb; trying to load $PROJECT_ROOT/lib/foo/bar.rb
require File.expand_path(File.dirname(__FILE__)) + "foo/bar"

is now written to rely on $LOAD_PATH:

# File: $PROJECT_ROOT/lib/foo.rb; trying to load $PROJECT_ROOT/lib/foo/bar.rb
require 'lib/foo/bar'

I removed the conditional checks from my constant initialization statements, and rake now runs unit tests without throwing any warnings.

The only way this can happen, is when bar.rb is required multiple times. Which shouldn't happen, since require doesn't load files that have already been loaded once.

It does, however, only use the path you pass to it to determine whether a file has already been loaded, at least in Ruby 1.8:

require 'bar'   # => true, file was loaded

require 'bar'   # => false, file had already been loaded

require './bar' # => true, OOPS, I DID IT AGAIN
# bar.rb:3: warning: already initialized constant BAZ

So, you are right: this could very well be an indication that there is something wrong with your dependency management.

Typical warning signs are

  • manually constructing file paths instead of just relying on $LOAD_PATH

    require "File.expand_path('../lib/bar', File.dirname(__FILE__))"
    
  • manipulating $LOAD_PATH anywhere except maybe the main entry point to your library:

    path = File.expand_path(File.dirname(__FILE__))
    $LOAD_PATH << path unless $LOAD_PATH.include?(path)
    

In general, my philosophy is that it's not my job as a library writer to figure out how to put my library on the $LOAD_PATH. It's the system administrator's job. If the sysadmin uses RubyGems to install my library, then RubyGems will take care of it, otherwise whatever other package management system he uses should take care of it, and if he uses setup.rb, then it will be installed in site_ruby, which is already on the $LOAD_PATH anyway.

Ruby core documentation quality

7 votes

I'm relatively new to Ruby and have limited time therefore I try out simple things. Recently I needed to create a file and because I'm lazy as hell, I run to Google. The result:

File.open(local_filename, 'w') {|f| f.write(doc) }

Shame on me, it is very straightforward, should have done it myself. Then I wanted to check what ruby magic the File class' methods offer or if there's any 'simplification' when invoking those methods, so I headed for the documentation here, and checked for the File class.

  • 1.8.6 documentation presents me with "ftools.rb: Extra tools for the File class" under 'File' class, which is not what I'm looking for.
  • 1.8.7 documentation seems OK for 'File' class, there are a plethora of methods. Except 'open'.
  • 1.9 documentation finally shows me the 'open' method.

And I had an almost same tour with Net::HTTP.

Do I exaggerate when I think good old Turbo Pascal's 7.0 documentation was better organized than Ruby documentation is right now? Is there any other source for the uninitiated to collect knowledge? Or is it possible that I just tumbled into a documentation hole and the rest are super-brilliant-five-star organized?

Thanks

You have to remember that Ruby is an object-oriented language, and a lot of objects in the Standard Library, are built on-top of other objects. In addition, many are extended by modules, which add in new functionality.

So, in the documentation you need to see what things an Object is built-upon. In File's case, it's built on top of IO, which will have a lot of the functionality you'd expect to find in a standard "file" class.

I agree that some of Ruby's documentation is disjointed. I think it's important to get a good book; I recommend the one we refer to as "The Pickaxe Book", AKA "Programming Ruby". There are many other good books, along with some good documentation on line, but this is a great go-to book. The [first edition] is available for free online; It is a bit outdated but still useful.

I'd recommend browsing through some of the other questions similar to this on SO for more suggestions.

I also keep links open to Ruby 1.9's Core and Keyword docs. And, finally, the top of the Ruby-Docs site points to lots of good info though you do have to pay attention to which version the docs are for.

Finally, don't ignore the built-in help: ri at the command-line is a fast source of info on your own machine that should contain documentation for the core and standard library, plus all the gems you have installed. ri open would have told you all the places "open" was defined. ri File.open would have given you a lot of information about that command.


When I started with Ruby, the biggest impediment to learning the language was the documentation. I still find it a lot easier to get info about Perl and Python, and feel like Ruby should use those as examples. That doesn't change my enjoyment of using Ruby though. It's a great language and once getting over the initial hump I like it more and more.

@phoffer recommends RubyDoc.info in the comment above. I hadn't seen that site but it looks good. I like that it shows what a class inherits from clearly.

Test whether a Ruby class is a subclass of another class

7 votes

I would like to test whether a class inherits from another class, but there doesn't seem to exist a method for that.

class A
end

class B < A
end

B.is_a? A 
=> false

B.superclass == A
=> true

A trivial implementation of what I want would be:

class Class
  def is_subclass_of?(clazz)
    return true if superclass == clazz
    return false if self == Object
    superclass.is_subclass_of?(clazz)
  end
end

but I would expect this to exist already.

just write

B < A # => true

(<= works too)

Can't install pg gem on Windows

6 votes

I've got 2 Ruby versions: 1.8.7 and 1.9.2 and PostgreSQL 8.3. I cant install pg gem on any of them. Getting this error:

C:/Development/Ruby187/bin/ruby.exe extconf.rb
checking for pg_config... yes
not recorded
checking for libpq-fe.h... no
Can't find the 'libpq-fe.h header
*** 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=C:/Development/Ruby187/bin/ruby
 --with-pg
 --without-pg
 --with-pg-config
 --without-pg-config
 --with-pg-dir
 --without-pg-dir
 --with-pg-include
 --without-pg-include=${pg-dir}/include
 --with-pg-lib
 --without-pg-lib=${pg-dir}/lib

I know it's a common problem, but I haven't found any working solution yet... Oh, I have added C:\Program Files (x86)\PostgreSQL\8.3\bin to my PATH.

Hello,

The message you're getting is a clear indication that you lack something for the correct installation of that gem:

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.

There is no Windows native version of latest release of pg (0.10.0) released yesterday, but if you install 0.9.0 it should install binaries without issues.

Anyhow, if you want to install the gem, you need a build environment installed. If you're using RubyInstaller, then you need the DevKit

Installation of the gem will only require you provide additional options to gem installation (like --with-pg-dir)

subst X: "C:\Program Files (x86)\PostgreSQL\8.3"
gem install pg -- --with-pg-dir=X:
subst X: /D

Can this be done in one regex ?

6 votes

I need a regex to match a string that:

  • has only digits 0-9 and spaces
  • all digits must be same
  • should have at-least 2 digits
  • should start and end with digits

Matches:

11
11111
1  1 1 1 1
1  1
11 1 1 1 1 1
1           1
1    1      1

No matches:

1             has only one digit
11111         has space at the end
 11111        has space at beginning
12            digits are different
11:           has other character

I know regex for each of my requirement. That way I'll use 4 regex tests. Can we do it in one regex?

Yes it can be done in one regex:

^(\d)(?:\1| )*\1$

Rubular link

Explanation:

^      - Start anchor
(      - Start parenthesis for capturing
 \d    - A digit
)      - End parenthesis for capturing
(?:    - Start parenthesis for grouping only
\1     - Back reference referring to the digit capture before
|      - Or
       - A literal space
)      - End grouping parenthesis
*      - zero or more of previous match
\1     - The digit captured before
$      - End anchor

What is this Ruby function doing?

6 votes

I am confused on how this returns:

def utc2user(t)
  ENV["TZ"] = current_user.time_zone_name 
  res = t.getlocal 
  ENV["TZ"] = "UTC"
  res
end

It first sets the ENV variable, then sets 'res' to the local value, then re-assignes ENV variable, then returns res?

Not sure I understand how this is convering from UTC to the user time zone?

The first line is setting the environmental time zone variable to the user's time zone in order to get the res value in the correct time for that user. If it didn't set it to the user's, the time would still be in UTC.

It then sets the environmental variable back to UTC time, which I assume is the application's default.

It then returns res.

\w in Ruby Regular Expression matches Chinese characters

5 votes

Hi guy,

I use the code below:

puts "matched"  if "中国" =~ /\w+/

it puts "matched" and surprised me, since "中国" is two Chinese characters, it doesn't any of 0-9, a-z, A-Z and _, but why it outputs "matched".

Could somebody give me some clues? thank you in advance and expect someone can answer me before 2011, :-).

Happy new year!

I'm not sure of the exact flavor of regex that Ruby uses, but this isn't just a Ruby aberration as .net works this way as well. MSDN says this about it:

\w
Matches any word character. For non-Unicode and ECMAScript implementations, this is the same as [a-zA-Z_0-9]. In Unicode categories, this is the same as [\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc}].

So it's not the case that \w necessarily just means [a-zA-Z_0-9] - it (and other operators) operate differently on Unicode strings compared to how they do for Ascii ones.

This still makes it different from . though, as \w wouldn't match punctuation characters (sort of - see the \p{Lo} list below though) , spaces, new lines and various other non-word symbols.

As for what exactly \p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}\p{Pc} means it matches, you can see on a Unicode reference list: