Best ruby questions in April 2011

do..end vs curly braces for blocks in Ruby

13 votes

A have a coworker who is actively trying to convince me that I should not use do..end and instead use curly braces for defining multiline blocks in Ruby.

I'm firmly in the camp of only using curly braces for short one-liners and do..end for everything else. But I thought I would reach out to the greater community to get some resolution.

So which is it, and why? (Example of some shoulda code)

context do
  setup { do_some_setup() }
  should "do somthing" do
    # some more code...
  end
end

or

context {
  setup { do_some_setup() }
  should("do somthing") {
    # some more code...
  }
}

Personally, just looking at the above answers the question for me, but I wanted to open this up to the greater community.

The general convention is to use do..end for multi-line blocks and curly braces for single line blocks, but there is also a difference between the two that can be illustrated with this example:

puts [1,2,3].map{ |k| k+1 }
2
3
4
=> nil
puts [1,2,3].map do |k| k+1; end
#<Enumerator:0x0000010a06d140>
=> nil

This means that {} has a higher precedence than do..end, so keep that in mind when deciding what you want to use.

P.S: One more example to keep in mind while you develop your preferences.

The following code:

task :rake => pre_rake_task do
  something
end

really means:

task(:rake => pre_rake_task){ something }

And this code:

task :rake => pre_rake_task {
  something
}

really means:

task :rake => (pre_rake_task { something })

So to get the actual definition that you want, with curly braces, you must do:

task(:rake => pre_rake_task) {
  something
}

Maybe using braces for parameters is something you want to do anyways, but if you don't it's probably best to use do..end in these cases to avoid this confusion.

How is writing a C interface easier in Ruby than Perl?

9 votes

According to the official ruby About page it's easier to extend Ruby with C than Perl. I'm not a (perl) XS guy, but I find it dirt simple to write something quick and simple with Inline::C, so why is it easier in Ruby?

Writing C extensions in Ruby is easier than in Perl or Python, with a very elegant API for calling Ruby from C. This includes calls for embedding Ruby in software, for use as a scripting language. A SWIG interface is also available.

Any further explanation from those that do more C extensions would be useful.

(Full disclosure, I am a Perl programmer)

The Ruby C API certainly looks much nicer than Perl's. It looks like a regular C library with functions that correspond to Ruby code. Perl's API is a mess of macros within macros within macros and magic threading flags. Using the Perl API outside of the Perl core is certainly a secondary concern. Ruby definitely wins on not being bowel clenchingly terrifying.

While Ruby has a better C API, Perl has the better tutorials on how to do anything with it. The generated Ruby documentation lacks any sort of cohesive tutorial or often any descriptive text at all. It's possible I'm looking in the wrong place but that's all that was offered. In contrast, the Perl API documentation is hand written prose with useful information about what each function does. In addition, there's over a dozen documents in the core docs about using Perl and C. I'd say Perl wins on docs.

FFI looks quite impressive. The closest thing Perl has to FFI is Inline::C which is a wrapper around the mess of XS. It's primary use is to inline C code into your Perl program, but you can also use it to access C library functions.

Here's a trivial example similar to nash's getpid example.

use Inline
  C             => Config       =>
  ENABLE        => "AUTOWRAP";

use Inline C => q{ int getpid(); };

print getpid();

Now, I am cheating because technically getpid returns pid_t on my system, but that's just an integer. FFI seems to have an awful lot of special cased code for getpid, so I suspect it's ease of use will correspond directly to whether FFI has already taken care of it. Trivial examples are trivial. It would be interesting to see what happens when typical complications arise, such as functions that return pre-allocated memory and have odd types and throw around structs.

While FFI and Inline::C can be used to do the same thing, how they do it looks very, very different. Inline::C is actually compiling and caching C code. FFI is somehow not doing any compiling. I'm not sure if that's really for real, or if the compilation is done for you at install time for common libraries.

In addition, FFI smooths the portability problems across the various Ruby implementations and their different ways of calling native APIs. This is something Inline::C doesn't have to do, and quite frankly it's amazing if it really works. One benefit is the FFI interface is much smoother than Inline::C. With Inline::C, it's very clear that you're writing a wrapper around a C compiler.

Is there a common/standard subset of Regular Expressions?

8 votes

Do the "control characters" used in regular expressions differ a lot among different implementations of regex parsers (eg. regex in Ruby, Java, C#, sed etc.).

For example, in Ruby, the \D means not a digit; does it mean the same in Java, C# and sed? I guess what I'm asking is, is there a "standard" for regex'es that all regex parsers support?

If not, is there some common subset that should be learned and mastered (and then learn the parser-specific ones as they're encountered) ?

See the list of basic syntax on regular-expressions.info.

And a comparison of the different "flavors".

Difference between plugins and Ruby gems?

7 votes

What is the difference between plugins and gems? What are the different uses of each? Where and why would you use one over the other?

Gem

  • Gem is a packaged ruby application using the packaging system defined by RubyGems.
  • Rails itself is a Gem.

    Rails gem is installed in jruby-1.0\lib\ruby\gems\1.8\gems\rails-1.2.3 as:

    DIR bin
    DIR builtin
    68,465 CHANGELOG
    DIR configs
    DIR dispatches
    DIR doc
    DIR environments
    307 fresh_rakefile
    DIR helpers
    DIR html
    DIR lib
    1,072 MIT-LICENSE
    11,969 Rakefile
    8,001 README
    The lib directory contains all the gem source code.

  • We can install,upgrade and query the gem version.If one uses a tool like my GemInstaller, one can easily automate the installation and loading of RubyGems with a single simple config file.

  • Gem installed for Ruby interpreter can be used system-wide by that interpreter.
  • Gem may be published as a plugin.
  • Can also be vendored in vendor/gems.

Plugin

  • Plugin is an extension of Rails Framework.
  • Can not be upgraded by using a command. To upgrade one have to uninstall and then install upgraded version.
  • Has to be hooked into rails application. (has to have init.rb)
  • Have an install.rb file.
  • Plugin cannot be published as a Gem.
  • Can only be used application wide.

Goldspike plugin is installed in vendor\plugins\rails-integration directory of the application as:
7,089 build.xml
1,141 LICENSE.txt
DIR plugins
6,675 pom.xml
1,447 README
DIR samples
plugins/goldspike directory consists of
24 init.rb
25 install.rb
DIR lib
549 Rakefile
536 README
DIR tasks
DIR test
The lib directory contains all the plugin source code.

Gem vs Plugins

  • Rails had a way of loading plugins from the vendor/plugins/ directory. This will most likely deprecate as Rails has added support for bundling gems with the project in the vendor/gems/ directory. The gem versions of rspec are the ones that are intended for everyday use. One should go with those unless you are supporting a Rails application in the 1.2.x family or earlier.
  • It often becomes quicker to check-in and check-out of a repository using Gems as you are not including the library in your actual application. There are often lesser problems using Plugins related to incompatibility arising concerning software versions among the distributed team.
  • General rule of thumb is to make Rails-specific functionality a plugin while making more general Ruby libraries into gems.

Is a system-wide install of RVM a bad idea?

7 votes

I'm confused about whether, on a server, you're supposed to install RVM as a regular user or do a system-wide installation, and, if the latter, how you're supposed to do things like bundle install without using sudo.

Is there any definite set of guidelines on what you're supposed to do as far as RVM is concerned on a server running Rails under e.g. Passenger and Nginx? In this type of environment, not all Ruby processes run under the same user, so I think that's where things get unclear as far as RVM and bundler are concerned.

How about just avoiding RVM all together on the server and just installing Ruby and gems the old fashioned way there? Is that preferable if you can get away with it?

You could install RVM as a regular user, although I don't see the point. Bundler is per-application and doesn't need sudo privileges since it can install your gems into a bundle directory that the bundle install user can access with, for instance:

bundle install --deployment

which will put them in vendor/bundle by default.

I think of RVM as a development tool for managing multiple ruby versions. On deployment machines I tend to either use system Ruby or install from source.

Ruby Dropped in Netbeans 7,how to use it in Netbeans7 ?

7 votes

In Netbeans 7 Ruby droped :

Although our Ruby support has historically been well received, based on existing low usage trends we are unable to justify the continued allocation of resources to support the feature.

how to use it in Netbeans 7 ?

I followed the steps described in this blog post - http://blog.enebo.com/2011/02/installing-ruby-support-in-netbeans-70.html and it works. Enjoy

Click Tools -> Plugins Click on
'Settings' tab Click on 'Add' button
to get Update Center Customizer popup
Set name to 'Beta 1' Set URL: to 'http://updates.netbeans.org/netbeans/updates/7.0/uc/beta/stable/catalog.xml.gz'
Press 'OK' Click to 'Available
Plugins' Click 'Reload Catalog' Choose
'Ruby and Rails' Pat yourself on the back

Is it worth changing from java/spring/hibernate to rails for a program that is undergoing massive changes?

7 votes

I have a project whose core domain is dramatically changing. It's possible to use 50% of the core functionality from this site and just add the 50% new functionality, but I am starting to consider that maybe it might be faster to simply redo the product in Rails. Development speed is very important.

There are some things I really like about java - the performance and scalability are very good. I am not a crappy Java developer, so my apps tend to run very well - better than the Rails sites I've seen. I've always accepted the idea that people probably just throw a little more money at the problem when it comes to using Rails, which probably works itself out in the end because of the insane productivity benefits.

I am actually quite agile with Java. I know it will still take me longer to add a basic entity to the system, but I am quick at it and I don't mind it that much. At least it's easy and straight-forward to do.

What I do mind is:

  • having to start/stop the server just to fix a route, lazy load exception, controller is going to wrong view, etc.
  • putting up with the fact that unit/integration tests sometimes have different results than the production environment (because annotations on controllers can't be tested, or lazy-loading exceptions occur during asynchronous service calls, or things like that). Knowing if your Jackson is marshaling your data properly is another Tomcat-only thing because it's handled by Spring. There are lots of things that go wrong after you have tested all that you can, and this frankly annoys the crap out of me.
  • putting up with the occasional maven/classloader problem that doesn't rear its ugly head until you deploy into tomcat. It gives the false impression that everything is "a-okay" when you are in your IDE.
  • having to put more effort to do database migrations than the ruby people ever have to.
  • putting up with framework bugs in Spring that block (it's happened about 5 times on this project since 2009) or Hibernate. I also don't like upgrading Spring Security and having them constantly change the configuration, apis and tag libraries over and over again. This is annoying.
  • wasting so much time uploading 58 MB war files to the server! These take me 12 minutes to upload whenever I need to deploy changes. If I forgot to do 'mvn clean' before I upload, Spring might complain that 2 beans exist with the same name because I moved one to a new package... and then I have to re-upload the whole stupid war file again. Why isn't "clean" run by default whenever you do 'mvn package' for?!?! Sometimes these frameworks and tools use the stupidest default settings. This is just so common in the Java world.
  • Having to spend hour(s) to figure out where a framework wants to plug-in your own custom implementation for something. This is very annoying. You can spend 2 hours sifting through Google and crappy documentation trying to figure out how to override Spring Security's authentication mechanism for example... and then spend only 5 minutes writing the actual implementation. Of course, they wrote paragraphs upon paragraphs explaining the architecture and how awesome it is, but nobody cares. For something so common, why not just give example source code and be done with it?
  • Waiting 10-15 seconds for Spring to start up whenever you want to run your integration tests. This is a drag.

There are a few things I like about Java though. Role-based access is very easy to do with Spring Security. Authentication is never that big of a gain, but I like the implementation inside of Spring.

I also like Spring's form-backing objects and @ModelAttribute. These are huge wins when it comes to controllers, and I don't know if Rails can do these things. I honestly never liked passing request parameters around in every action - Spring MVC is actually a lot easier to use when it comes to this common bloat.

Being able to cache really massive structures in memory and have them stay in memory when you start the application is also highly desirable, especially for this application actually. I have an in-memory thesaurus and grammar checker that needs to get called hundreds of times per request, so in memory is pretty much the fastest option for me.

Even still, I think I could rebuild what I have in 2-3 weeks, and then add all of the new features in a few weeks using rails.

On the bright side, all of the really well-designed css, html and javascript could be ported over with very little problems.

I'd appreciate some advice on the subject before I continue.

PS: I could also go to Spring-ROO... but that would also be a considerable rework. I was never using JPA - I was using Hibernate directly. I am also not using JSP's - I am using Freemarker.

It takes more time to get good at Ruby, and Rails. I worked as an independent contractor as Spring and Hibernate expert myself, but I felt strangled by java and it's web frameworks so I decided to learn Ruby on Rails.

I would advice you to learn Ruby, from what I read you would probably master it, although get pretty frustrated with the very different way the use the ORM. I had issues with it, used to working on aggregate roots in Hibernate to the ActiveRecord one class one table kind of pattern. But hey, you could easily try out MongoDB to have some real fun.

Ruby is

  • less code
  • it's fast and scalable (slower than java on the specific tasks, but you get rid of stacks of layers.)
  • the problems are more often; which gem should I use. Luxorious!
  • a unique, big, sharing and caring open source community
  • nice frameworks, as Rails and Sinatra
  • powerful.
  • fun!

Would I advice you to do the project you describe in Ruby.

NO.

Not if speed of development matters. You will be slower, trust me. There's a lot to learn, it's conventions are not familiar to a java programmer and when you get stuck, lots of hours fly by.

The best option would be to hire a senior ruby developer to pair up with you and teach you. Be a good apprentice and you'll learn fast. Faster than me, I had to learn most by myself, which is really inefficient.

Good luck!

Need a memorable explanation of a proc and lambda

7 votes

I've tried reading about procs and lambda's but I have to keep re-reading the definition.

Can someone explain it to me in a way that is clear and memorable?

A few resources:

There's also an entire chapter in the Read Ruby 1.9 book.

What are the key semantic differences between Ruby and Javascript

6 votes

If one were to implement Ruby on top of a Javascript engine (either in the browser or on top of standalone V8 or Spidermonkey), what would be the key impedance mismatches between the Ruby and JS object models ?

The most in-your-face one is obviously the fact that ECMAScript is prototype-based and Ruby is class-plus-mixin-based. Also, in Ruby, encapsulation is done with objects, in ECMAScript with closures.

However, my guess is that Ruby's control flow constructs are going to be a much bigger hurdle than its object model. After all, James Coglan's JS.Class is basically an implementation of Ruby's object model in ECMAScript and it's not that big.

ECMAScript simply lacks the tools needed to build your own control-flow constructs on top of it. Typically, you need either GOTO, continuations or proper tail calls. If you have one of those, you can easily implement everything else: exceptions, loops, switches, threads, Fibers, generators, coroutines, … you name it.

But ECMAScript doesn't have them (and for good reason, at least in the case of GOTO). The only control-flow construct ECMAScript has that is powerful enough to be able to build other constructs on top of is exceptions. Unfortunately, those are pretty slow. (Nonetheless, they have been used as an implementation substrate, for example in the Microsoft Live Labs Volta compiler, which used ECMAScript exceptions to implement .NET exceptions, iterators, generators and even threads.)

So, basically you are stuck with implementing at least your own call stack if not an entire interpreter (as is the case with HotRuby), performing global CPS transforms or something like that.

Basically, what you want from a Ruby engine running on top of ECMAScript, is

  1. a faithful implementation of the RubySpec (specifically the control-flow constructs such as threads, fibers, throw/catch, exceptions etc.),
  2. performance and
  3. tight integration with ECMAScript (i.e. the ability to pass objects and call methods back and forth between the two languages).

Unfortunately, when you have to resort to tricks like managing your own stack, doing CPS transforms, building on top of exceptions, … it turns out that you can only pick two of the three goals.

string.match(regex) vs regex.match(string)

6 votes

What's the difference between string.match(regex) and regex.match(string) in Ruby? What's the justification for having both those constructs in the language?

I thnk that, intuitively, match, or the related method =~, expresses some kind of equality, as reflected in the fact that =~ includes the equality = and the equivalence ~ relations (not in ruby but in mathematics). But it is not totally an equivalence relation, and among the three axioms of equality (reflexivity, commutativity, transitivity), particularly commutativity seems reasonable to be maintaind in this relation; it is natural for a programmer to expect that string.match(regex) or string =~ regex would mean the same thing as regex.match(string) or regex =~ string. I myself, would have problem remembering if either is defined and not the other. In fact, some people feel it strange that the method ===, which also reminds us of some kind of equality, is not commutative, and have raised questions.

solving a problem with map reduce

6 votes

I want to simulate in ruby my implementation of the map and reduce functions for a system like hadoop to verify that the idea works at least.

I have the following problem. I have two lists of elements:

List1
3 - A
4 - B
5 - C
7 - D
8 - F

List2
2 - A
8 - B
6 - C
9 - D
4 - E

I need to build a common list that includes the sum of the numbers associated with the alphabets common in the two lists:

commonList
5 - A
12 - B
11 - C
16 - D

I want to make a ruby script with the map and reduce operations to solve this problem. I am unsure how to tackle on this problem or what procedure to follow to simulate this in a ruby script.

Any help appreciated.

You could try by considering the elements given in MapReduce wikipedia article:

  • an input reader - in your case this would probably be a method call on [key, value] pair from your input hashes.
  • a Map function - you already have keys you should be processing your data by, so your map worker would just return the [key, value] pair it got as an input
  • a partition function - a method which would assign a reduce worker based on the key. In your case it could be simply key.hash % REDUCER_COUNT.
  • a compare function - I don't think this is applicable in your case as you don't need values to be processed in any particular order.
  • a Reduce function - would be given [key, list] pair, list being list of values associated with the key. It would return the sum of list if list is more than one element long (as you want only elements appearing in both input hashes processed).
  • an output writer - could be plain Hash in your example.

And here's my (over)simplified implementation of the above.

Good Cucumber examples in the wild?

6 votes

I've tried Cucumber for a few projects a couple of years ago and am looking to give it another go. I don't really need another "Beginning Cucumber" article. Instead, I'd like to see some actual uses in the wild—one's that other Cucumber users would consider idiomatic and antipattern-free.

So, in your opinion, what are the best examples of actual Cucumber specs in large projects?

You can read diaspora's cucumber tests. It's a pretty big project so I think you can learn something from it.

How do you spawn an EventMachine "inside" a Rails app?

6 votes

I've got a Rails application, and am looking to add some sort of WebSocket support to it. From various googling, it appears that the best Ruby based WebSocket solution is em-websocket running on EventMachine.

I was wondering if there was a way to "integrate" an EventMachine reactor into Rails? Where do I put the initialization code? Is this the proper way to accomplish this?

I've seen this example that falls back on Sinatra to do an EventMachine GET request, but that isn't quite what I'm looking for.

Any help is appreciated.

I'd try using em-synchrony to start a reactor in a fiber. In a rails app you can probably start it in an initializer since it sounds like you just want to leave the reactor running to respond to websocket requests. As suggested by the other answers I think you want to either setup socket communication with your reactor or use one of the asynchronous clients to a data store which both your reactor and rails code can read from and write to to exchange data.

Some of my coworkers put together some examples of starting EM reactors on demand in ruby code to run their tests within EventMachine. I'd try using that as a possible example; raking and testing with eventmachine

What is the preferred way to implement settings in a Ruby on Rails 3 application?

5 votes

I'm building a Rails 3 application that will have user-specific settings (looks, functionality, etc) and I was seeking some simple advice on whats the preferred way of actually implementing settings.

Do you prefer to have a dedicated model for this stuff? Are hashes acceptable to store in a database field? Do you prefer cookies or sessions over the database? Is an STI object best?

Maybe list some pros or cons to each different method if you can.

Thanks.

Hi, i've same situation like you, user specific setting. In my apps i prefer creating a model to store user's configuration i've User model and User_configuration model, where the relationship is one-to-one.

class User < ActiveRecord::Base
  has_one :user_configuration
end

class UserConfiguration < ActiveRecord::Base
  belongs_to :user, :dependent => :destroy
end

Or if you prefer using Hash and store it to database is possible to mark your field as serialize

class User < ActiveRecord::Base
  serialize :preferences, Hash
end

you can see it at http://api.rubyonrails.org/classes/ActiveRecord/Base.html

pros: - so far i've doesn't have any problem, it easy to maintenance

cons: - request more table in database

May be it could help you thanks.

Setting the cache_store in an initializer

5 votes

I'm trying to use redis-store as my Rails 3 cache_store. I also have an initializer/app_config.rb which loads a yaml file for config settings. In my initializer/redis.rb I have:

MyApp::Application.config.cache_store = :redis_store, APP_CONFIG['redis'] 

However, this doesn't appear to work. If I do:

Rails.cache

in my rails console I can clearly see it's using the

ActiveSupport.Cache.FileStore

as the cache store instead of redis-store. However, if I add the config in my application.rb file like this:

config.cache_store = :redis_store 

it works just fine, except the app config initializer is loaded after application.rb, so I don't have access to APP_CONFIG.

Has anyone experienced this? I can't seem to set a cache store in an initializer.

After some research, a probable explanation is that the initialize_cache initializer is run way before the rails/initializers are. So if it's not defined earlier in the execution chain then the cache store wont be set. You have to configure it earlier in the chain, like in application.rb or environments/production.rb

My solution was to move the APP_CONFIG loading before the app gets configured like this:

APP_CONFIG = YAML.load_file(File.expand_path('../config.yml', __FILE__))[Rails.env]

and then in the same file:

config.cache_store = :redis_store, APP_CONFIG['redis']

Another option was to put the cache_store in a before_configuration block, something like this:

config.before_configuration do
  APP_CONFIG = YAML.load_file(File.expand_path('../config.yml', __FILE__))[Rails.env]
  config.cache_store = :redis_store, APP_CONFIG['redis']
end