How can I profile Ruby code in 1.9.2? - ruby

What can I use to profile code in 1.9.2? All of the versions of ruby-prof I've found segfault against 1.9.2.
For instance, when I add
gem "ruby-prof"
to my Rails project's Gemfile and run
bundle
bundle exec ruby-prof config/environment.rb
I get a segfault.
Is there a new profiling gem in town? Is there a way to make ruby-prof play nice?

Not sure it helps but I stumbled on this which may add a bit more clarity or lead you down a different path: http://www.devheads.net/development/ruby/core/segmentation-fault-when-using-ruby-prof-and-ruby-192.htm. You may want to check out wycats' fork based on that thread: https://github.com/wycats/ruby-prof
Also, I have not tried it out myself and it may not be exactly what you are looking for but Aman of Github fame has a port of google-perftools for Ruby:
https://github.com/tmm1/perftools.rb

As #chris.baglieri suggested, you can use the perftools.rb gem for profiling Ruby 1.9 code.
gem install perftools.rb
Then
require 'perftools'
PerfTools::CpuProfiler.start('profile_data') do
# something cpu-intensive
end
`pprof.rb --text profile_data profile.txt`
`pprof.rb --pdf profile_data profile.pdf`

You can use another popular profiler tool - MethodProfiler
It's very handy to find slow method in the target class.

Related

How do I get rrdtool from homebrew to work with ruby on macOS

In our Rails application we do require 'RRD' at some point, but that results in a cannot load such file -- RRD. So obviously I used homebrew to install rrdtool, but the error remains.
The docs at https://oss.oetiker.ch/rrdtool/prog/rrdruby.en.html provide two options:
Either:
$: << '/path/to/rrdtool/lib/ruby/1.8/i386-linux'
require "RRD"
In my /opt/homebrew/Cellar/rrdtool/1.8.0/lib directory there's no mention of ruby, which is because of the --disable-ruby-site-install flag in the formula, because when I skip that flag I do actually get something: /opt/homebrew/Cellar/rrdtool/1.8.0/lib/ruby/2.6.0/universal-darwin21. However replacing the path/to string with this path still gives the error.
Or:
If you use the --ruby-site-install configure option you can drop the $: line since the RRDtool module will be found automatically.
Which is a little confusing (and probably outdated) because here it seems that ruby site install is disabled by default and you have to enable it proactively, whereas in the formula it's actually actively disabled.
Either way: both options didn't do the trick for me and if there's a solution without homebrew that's also fine.
For good measure: I'm on macOS Monterey
TL;DR
For the most part, I'd say that using a non-standard gem without a Ruby version manager is your main issue. There are instructions on the rrdruby site for installing it, but they don't follow typical conventions, so your mileage will vary.
Some Practical Suggestions
The require keyword is for gems, not binaries. You need to have an rrdtool-related gem installed, available to your Ruby instance (usually through a Bundler Gemfile or gemspec, or via the RUBYOPTS environment variable or your in-process Ruby $LOAD_PATH), and then require the correct name of the gem in your code. For example, using the older rrd-ffi gem:
# use sudo if you're installing it to the system,
# but I would strongly recommend a ruby version
# manager instead
gem install rrd-ffi
# in your Ruby class/module file
require "rrd"
For the gem you seem to be using, you have to compile the gem first to make it usable, and then ensure it's available in your Ruby $LOAD_PATH (or other gem lookup mechanism) before trying to require it. The error message you're seeing is basically telling you that a gem with that name is not available as called within any of the standard lookup locations.
Again, I'd suggest reading the build documentation for your gem, and then seeing if you can install it as part of a Bundler bundle, RVM gemset, or other non-system approach if you can. Otherwise, follow the directions for the rrdruby tool, which is not available as a standard Rubygems.org gem, in order to make it available before trying to require it.
Beware of Outdated or Non-Standard Gems
Most of the RRD gems I found were quite old; most were 7-8 years old or older, so their compatibility with current Rubies is potentially suspect. The gem-builder you're using is newer, but doesn't seem to be designed as a standard gem, so you need to build it and install it in a suitable lookup path before it can be required. Installing gems as system gems is almost always a bad idea, so I'd strongly recommend building it from source and using a ruby version manager rather than following the rrdtool author's atypical suggestions. YMMV.

Find out which gems require native c extensions from a Gemfile?

I just recently started shifting attention towards deploying Ruby apps atop TorqueBox which of course is built atop Jruby. Hitherto I have been basically performing a bundle install and then tackling each gem along the way to jrubydom, but I've hit a couple gems that have taken me some considerable time to resolve due to needing to reimplement large portions of them.
Is there a way to invoke bundler or rubygems to run through all gems and their deps to test if they require native c extensions and then return such a list? It sure would be nice to tackle some of the more minor items or even to know if it is worthwhile to tackle a project in terms of moving it to jruby.
Based on the fact that gems with native extensions usually have an /ext directory, I made a simple oneliner that finds these gems:
puts `bundle show --paths`.split("\n").select{|dep| File.directory?("#{dep}/ext") }.map{|dep| dep.split('/').last }.join(', ')
You can do this on the command line with this command:
$ bundle show --paths | ruby -e "STDIN.each_line {|dep| puts dep.split('/').last if File.directory?(File.join(dep.chomp, 'ext')) }"
You can use JRuby Lint for that. It will will check for some gems requiring C extension and even list alternative (based on this list).

Cucumber with Ruby: Can it be used from a gem?

I'd like to develop some reusable step definitions and scenario outlines for Cucumber in Ruby.
I've scoured the Cucumber wiki but there seems to be no info on use of Cucumber with Ruby gems.
Is there support for execution of a feature from an installed Gem?
Or would a user have to manually change to the gem installation directory and explicitly referenced the feature(s) to run from there?
If I understood your question correctly, all you need is to create some lib for reusable definitions and steps, and then require this lib(or gem) in features/support/env.rb
Here is a gem does exactly the same as you need, you can use it as a reference: https://github.com/jayzes/cucumber-api-steps
Look at the features this gem provide: https://github.com/jayzes/cucumber-api-steps/blob/master/features/request.feature The gem created some reusable parts.
Turns out cucumber --help shows the way:
cucumber -r gem-name feature-name.feature
UPDATE: This doesn't work. Any other suggestions?
There is a cucumber gem which installs the binary cucumber.
Running this command, will assume default settings. This means it will look under ./features relative to the current path for files with the .feature extension. It will expect ./features/step_definitions to hold files with *_step.rb, where it will search for steps.
Edit: never mind, I misread your question and thought you wanted to know about the cucumber gem and its default paths.

rcov outside rails

This may seem obvious but I don't find a way to run Rcov or coverMe outside a Rails project.
I would like to use it with Rspec 2.5
I am using Ruby 1.9.2 so I guess this may be the problem.
I also would like not to use rake tasks but a command on the command line. I have tried several things and the best result I got is Rcov report for :
/var/lib/gems/1.9.1/gems/rcov-0.9.9/lib/rcov/code_coverage_analyzer.rb
and
/var/lib/gems/1.9.1/gems/rcov-0.9.9/lib/rcov/code_coverage_analyzer.rb
No idea why
Check out http://ruby-toolbox.com/categories/code_metrics.html for some alternatives to RCov if using Ruby 1.9 is the problem.
SimpleCov, it runs awesome outside the Rails box.
http://rubydoc.info/gems/simplecov/0.5.4/frames
The latest available version of rcov (0.9.8) still doesn't have good support for 1.9.2. You can try to run it on your project by doing:
rcov spec/*.rb
But you'll most likely get something like:
** WARNING: Ruby 1.9 Support is experimental at best. Don't expect correct results! **
And then some errors after that.

gem command . What does that mean

Sometimes I have seen following code.
gem 'factory_girl','= 1.2.3'
require 'factory_girl'
I tried to look at gem doc but could not find answer to the question of what does the first line do in code above?
What you're looking for in the gem docs is about Coding with Rubygems.
The first line basically says "Hey, go get this gem with this version" from the install directory for gems and load it into the environment. This is mainly to help you add version dependencies to your requires instead of just doing require 'factory_girl' by itself.
Edit: To add on to Jörg's point below, I thought that Ryan Tomayko had a pretty good short and sweet article about why doing this is "wrong".
As #theIV already explained, this activates the factory_girl gem, using exactly (because of the = sign) version 1.2.3.
Note, however, that this is very bad practice and should never be done. If you activate gems manually inside your code, it means that people who do not use RubyGems can no longer use your code.
RubyGems is a package manager. Your code should never care about what package manager was used to install it. Some people prefer RubyGems, some dpkg/APT, some RPM/YUM, some RPM/APT, some RPM/URPMI, some RPM/YaST2, Portage, FreeBSD ports, pkgsrc, MacPorts, slashpackage, CoAPP, Conary, Slackware. There's tons of them. Some people like not to use any package manager at all. Or, they use RubyGems just for downloading, but then unpack the gem into their vendor directory.
All of this cannot possibly work, if you use the gem method in your code.

Resources