Ruby Autocompletion (pry gem) in Spacemacs/Emacs - ruby

I've started to use Spacemacs and I have a trouble with ruby autocompletion. When Gemfile contains pry autocompletion works fine, but if pry is not present in the Gemfile, I get the error cannot load such file -- pry after :robe-start or SPC m s i. I don't want to add unnecessary gems to the Gemfile and looking for the solution to use globally installed pry.
I researched and found the next solutions: Add Pry.config.eager_load! to .pryrc or add pry to global gemset but any of them did not help.

Related

Pry is not a module

Ok, as #tim-moore asked, I will post it in new question.
Ok, so I wanted to make gem using bundle. Pry extension gem require that gem start with pry- as mentioned here.
I used:
bundle gem pry-name
but it messed up my file structure
create pry-name/pry-name.gemspec
create pry-name/lib/pry/name.rb
create pry-name/lib/pry/name/version.rb
As you can see it created lib/pry directory. I know it's gem's style to created such structure but now I pry cannot load this gem automatically
One solution from my question was:
create pry-name.rb that contain only require 'pry/name'
After I have done this, and build gem, I started pry:
This message appear:
require 'pry-name' # Failed, saying: Pry is not a module
As for my guesses:
I'm creating commands writing something like this:
Pry::Commands.create_command "name-of-command" do
# my code goes here
end
and, as ruby find Pry::Commands. it want require it from lib directory not from Pry gem.
What does this error mean. Why it doesn't work. How make it work keeping in mind gem and pry requirements(pry gem starts with pry- and gem will create another directory(ies) when someone use - for example: gem pry-name will make pry/name)
Everywhere in your newly-created gem where it has module Pry, change it to: class Pry. Since Pry is already defined (as a class), you cannot redefine/reopen it as a module.

Can't get awesome_print gem to work

awesome_print looks like a pretty nice gem, so I wanted to try it out.
I went to one of my projects and did:
gem install awesome_print
and it says one gem installed, documentation installed, etc.
Then, while I am in that project, I went to my Rails console to try it out, but when I did a require "awesome_print" as their help file says, I get a "cannot load such file".
Has anyone got this to work?
gem install will put the gem code on your computer, but unless the gem's source code files are on your load path, require won't be able to find them. bundle exec looks at the nearest Gemfile.lock and adds the source code for all the gems listed there to your load path. Rails initialization includes getting Bundler to do this for you.
One solution is to add awesome_print to your Gemfile. However, this will cause your application to have awesome_print as a dependency. Alternatively you can manually add the awesome_print library to your load path after starting up the Rails console and then requiring it:
$ rails c
> $LOAD_PATH << path/to/awesome_print-x.x.x/lib
> require 'awesome_print'
> ap {foo: {bar: {baz: :qux}}}
If you're using RVM, the path is likely to be something like:
~/.rvm/rubies/ruby-x.x.x-pxxx#your_gemset_name/gems/awesome_print-x.x.x/lib
Add it to your Gemfile like this:
gem 'awesome_print', :require => 'ap'
I add it to the development group, since that's the only time I need it. The gem doesn't have any other gem dependencies, so I routinely add it to my Gemfile.
Also, add these two lines to your ~/.irbrc file to set ap to be your default pager:
require "awesome_print"
AwesomePrint.irb!
Note that if you use this, however, any projects where awesome_print is not installed in its Gemfile will raise this error when you run rails c:
cannot load such file -- awesome_print
Depending on whatever else you may have in your ~/.irbrc file, this can cause other side effects, such as messing up your prompt. To avoid these, simply add the two lines to the very end of that file.
install it :
$ gem install awesome_print
include it in you GemFile, if you want :
gem 'awesome_print', :require => 'ap'
add this line to the file ~/.irbrc :
require 'awesome_print'
AwesomePrint.irb!
restart your shell!
just a note: I did this and it didnt work right away, probably need to restart the computer... or I just needed to close all shell tabs and open the terminal again!
Install the gem on your machine
gem install awesome_print
Get the path to which it has installed
gem which awesome_print
Add the following configuration to your ~/.irbrc and ~/.pryrc. This will load Awesome Print whenever you fire an IRB or a pry session.
*Remember $LOAD_PATH will hold whatever you got from typing gem which awesome_print
# ~/.irbc and ~/.pryrc
$LOAD_PATH << "~/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/awesome_print-1.8.0/lib/"
require "awesome_print"
AwesomePrint.irb!
If you are looking to install it without having it in your Gemfile, this is how to do it:
$ gem install awesome_print
I was running into an issue where it was installing successfully but it not in the right directory.
In that case just put this in your .bashrc, this will set the load path:
export PATH="/home/user/.gem/ruby/2.3.0/bin:$PATH"
PATH="`ruby -e 'puts Gem.user_dir'`/bin:$PATH"
replace 2.3.0 with the version of ruby you are working with.
replace user with your username or if you are using vagrant then replace with vagrant
reload your .bashrc or exit the Terminal to reload changes, then install the gem again.
In my case, I struggled with PATHs and such, while missing something obvious!
# which ruby
/usr/bin/ruby
# ruby -v
ruby 2.3.7p456 (2018-03-28 revision 63024) [universal.x86_64-darwin17]
# locate bin/ruby
/usr/bin/ruby
/usr/local/Cellar/ruby/2.7.2/bin/ruby
/usr/local/opt/ruby/bin/ruby
# /usr/local/opt/ruby/bin/ruby -v
ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin17]
#
Aha! Version crud. I was running an old ruby. Thanks, Apple!
# sudo mv /usr/bin/ruby /usr/bin/ruby_2.3.7
# sudo ln /usr/local/opt/ruby/bin/ruby /usr/bin/ruby
Solved the problem!
There is probably something I could have told brew to do to fix things, but I was impatient. :-)

How to use gems not in a Gemfile when working with bundler?

When using bundler with a project in general and Rails specifically, you have access only to gems defined in your Gemfile. While this makes sense, it can be limiting. Mostly I find it limiting when I want to use a certain RSpec formatter that the rest of the team doesn't use. Unless it's in the Gemfile, it isn't accessible.
Any way around it or I have to add it to Gemfile?
Update: my problem wasn't Bundler but Spork. When running RSpec without Spork I had no problem of using whatever formatter I wanted.
Update #2: it looks like that using Bundler is still the cause of the problem. The difference between using Spork and not using Spork, is that when running RSpec without Spork, it loads the formatter before loading your project and getting into the Bundler "sandbox".
With Bundler:
$ bundle exec irb
>> require 'fivemat'
LoadError: cannot load such file -- fivemat
from (irb):1:in `require'
from (irb):1
from /Users/arikfr/.rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in `<main>'
Without Bundler:
$ irb
>> require 'fivemat'
=> true
In ChiliProject we allow users to create a Gemfile.local which is included into the main Gemfile on load. This allows users to specify additional gems without having to change our Gemfile to ease updates.
For that, we have included the following code at the bottom of our Gemfile.
gemfile_local = File.expand_path('Gemfile.local', __dir__)
if File.readable?(gemfile_local)
puts "Loading #{gemfile_local}..." if $DEBUG
instance_eval(File.read(gemfile_local))
end
The Gemfile.local itself is excluded from the repository via .gitignore.
I assume that none of these answers have been chosen as correct because they don't do a great job of solving the problem: having additional gems that you can use that by default don't require any changes to files already in the repository to achieve. That is, you don't have to modify any files, and you don't have to live with remembering not to check in your local changes. Here's how I do it.
The idea is basically inverting the dependencies of Holger's answer, such that there's no need to modify the shared Gemfile. Bundler allows one to specify which file is to be used as the gemfile, but strangely the documented methods do not apparently work with its configuration file and will not be fixed. There is a somewhat obscured feature of Bundler that any of the configuration options can be set in an environment variable or passed on the command line. Running all of your commands as bundle [command] --gemfile [yourgemfile] or BUNDLE_GEMFILE="[yourgemfile]" bundle [command] will cause Bundler to read whatever gemfile you want it to. I highly recommend using the environment variable approach, and either creating an alias or exporting the variable for your current session, particularly as I was unable to use the command line switch with the "exec" command.
Therefore, I run rspec like this: BUNDLE_GEMFILE="[mygemfile]" bundle exec rspec [filename], and I have the first part of this aliased as bem in my bashrc. Works like a charm.
Then, you should setup your source control to ignore your Gemfile, either in the project's .gitignore or, to keep the project entirely hygienic without changing even its .gitignore, to your personal global ignore file (which is by default in ~/.config/git/ignore and has the same format as a project's gitignore file).
One other thing to note is that Bundler will create a lockfile based on the Gemfile's name. This is super handy, as it keeps you from overwriting your project's Gemfile.lock if it's checked in, but you need to ignore this new lock file as well. If your gemfile is Foo.bar, look for Foo.bar.lock.
Finally, you can do something similar to Holger's suggestion in your custom Gemfile:
source "http://rubygems.org"
gem "fivemat"
instance_eval(File.read(File.dirname(__FILE__) + "/Gemfile"))
and you're good to go, as long as you remember to specify your Gemfile.
You can use something like this in your Gemfile:
gem 'foo' if ENV['ENABLE_FOO_GEM']
Then just set ENABLE_FOO_GEM in your environment.
export ENABLE_FOO_GEM=1
The gem will be disabled by default, but easily turned on (permanently) by anyone who wants to use it.
Add to .gitignore
Gemfile.local
Gemfile.local.lock
Add to the project a Gemfile.local.sample file with the following content:
# Include gems that are note meant to be part of the project but for development purposes
# That's why Gemfile.local and Gemfile.local.lock must be git-ignored
# To use these gems:
# 1. Create a "Gemfile.local" file (at same level of "Gemfile")
# 2. Prepend "BUNDLE_GEMFILE=Gemfile.local" before "bundle install" or "bundle exec rails c" and so forth.
eval_gemfile "./Gemfile"
group :development, :test do
# Suggested gems
gem "awesome_print", require:"ap"
gem "hirb"
gem "pry"
gem "pry-byebug"
gem "pry-rails"
gem "meta_request"
# My gems
gem "fivemat"
end
I believe the gem Devpack provides the functionality you are looking for.
The gem allows you to add a single gem to your Gemfile which will permit any developer to configure their own preferred set of development gems either for an individual project or globally by creating a .devpack file containing a list of gems.
(I am the author of this gem; I came across this post while developing it so thought it may be worth adding).
In case you still decide to do this (horrible idea):
You can add ruby code to your Gemfile to load a ~/.gemfile (or such) if it exists.
Something like:
eval(IO.read('~/.gemfile'), binding) if FileTest.exists?("~/.gemfile")

While running bundle exec irb, need access to machine-only gems

How do I make bundle exec irb aware of system-gems?
To load a project, we're using bundle exec irb. To make my life in irb a bit easier I had planned on using irb_rocket (with wirble and ruby-terminfo).
When loading just plain irb, it works as expected. However when using bundle exec irb, it can (obviously) not find my systems-gems.
I do not have the option to alter the gemfile, unless I can somehow make it only apply to my machine.
If it's worth anything; os x, source-control in git, ruby versioning in rbenv.
When requiring with the full paths of the gems, irb_rocket requires terminfo again which then throws a LoadError on require 'terminfo.so'. Changing the gem locally is not really what I want to do, but I guess it would work.
You could use Pry instead of IRB together with pry-debundle. If this is a Rails project you can just add pry-rails to your Gemfile so that it will be used as Rails console.

Ruby: How to include/install .bundle?

I'm new to Ruby. I have a .bundle file. I put it in the source folder and did
require('my.bundle')
But when I call the methods in the bundle, the definition is not found. Do I have to install them or include them in some other way to access them?
I am on Ruby version 1.8.7 (latest version on Mac).
I highly recommend using RVM to manage your Ruby installation, including your gems, so if you don't already have that, get it and follow the instructions for installing it. Make sure you do the part about modifying your bash startup script or you'll see weird behavior, like the wrong Ruby being called. Also, use the steps in "RVM and RubyGems" to install your gems or you can run into weird behavior with gems being installed under the wrong or an unexpected Ruby.
Second, use the gem command to install gems:
gem install gem_to_install
replacing "gem_to_install" with the name of the gem you want, and it will be installed into the appropriate gem folder for your Ruby.
If you are on Ruby 1.92, and trying to require a gem to use as a module in your code, use:
require 'gemname'
if it is installed via the gem command. And, if it is a module you wrote or have in your program's directory or below it, use:
require_relative 'path/to/gem/gemname'
If you are on a Ruby < 1.9 you'll also need to add require 'rubygems' above your other require lines, then use require './path/to/gem/gemname'.
Thanks, but my .bundle is not in gems. How do I install/require a .bundle file I already have?
If you wrote it look into rubygems/gemcutter or bundler for info on bundling and managing gems.
You can install a gem without using the app by going into the directory containing the gem and running setup.rb. See http://i.loveruby.net/en/projects/setup/doc/usage.html for a decent writeup or the official docs at: http://docs.rubygems.org/read/chapter/3

Resources