Undefined method for ri inside of IRB - ruby

Inside of the interactive ruby console if i type ri then i get an undefined method error, do i explicitly have to install documentation somewhere to get this to work?
irb(main):015:0* ri --help
NoMethodError: undefined method `-#' for nil:NilClass
from (irb):15
from /usr/local/lib/ruby/site_ruby/1.8/rubygems.rb:295
irb(main):016:0> ri Array
NoMethodError: undefined method `ri' for main:Object
from (irb):16
from /usr/local/lib/ruby/site_ruby/1.8/rubygems.rb:295

You probably do not want to do that. What you should be doing is exiting to the shell (or preferably, open a new terminal tab or screen session) and running ri separately, which is a program, from there. If you really, really, want to do what you're doing, you can always use backticks to run ri --help, or any other shell command.
irb(main):015:0* `ri --help`

In fact ORI gem can bring RI to your IRB console and give some more neat class exploration functions.
Watch intro screencast.
Setup (~/.irbrc)
require "rubygems"
require "ori"
Request RI on a Class
Array.ri
String.ri
[].ri
"".ri
5.ri
Request RI on a Method
String.ri :upcase
"".ri :upcase
[].ri :sort
Hash.ri :[]
Request Interactive Method List
String.ri //
"".ri //
"".ri /case/
"".ri /^to_/
User.ri /^validates_/
etc.

Just --help:
irb(main):040:0> --help
Enter the method name you want to look up.
You can use tab to autocomplete.
Enter a blank line to exit.
>> Array
←[0m←[1;32mArray < Object←[m
(from gem backports-1.18.2)
------------------------------------------
To return into IRB, I pressed Crtl+C, but there probably is some some quit-command.

Related

Why word 'translate' is messing irb?

I don't understand why my method translate undefines start_with? method and is messing something in irb, so I can exit irb only by pressing Ctrl+d, not exit or quit:
>> "hello".respond_to?(:start_with?)
=> true
>> def translate(string)
>> if string.start_with?("a", "e", "i", "o", "u")
>> string += "ay"
>> end
>> end
NoMethodError: undefined method `start_with?' for #<RubyVM::InstructionSequence:0x00000001d4c960>
from (irb):3:in `translate'
from /usr/local/rvm/rubies/ruby-2.3.0/bin/irb:11:in `<main>'
>> "hello".respond_to?(:start_with?)
NoMethodError: undefined method `start_with?' for <RubyVM::InstructionSequence:irb_binding#(irb)>:RubyVM::InstructionSequence
from (irb):3:in `translate'
from /usr/local/rvm/rubies/ruby-2.3.0/bin/irb:11:in `<main>'
>> exit
NoMethodError: undefined method `start_with?' for <RubyVM::InstructionSequence:irb_binding#(irb)>:RubyVM::InstructionSequence
from (irb):3:in `translate'
from /usr/local/rvm/rubies/ruby-2.3.0/bin/irb:11:in `<main>'
>> quit
NoMethodError: undefined method `start_with?' for <RubyVM::InstructionSequence:irb_binding#(irb)>:RubyVM::InstructionSequence
from (irb):3:in `translate'
from /usr/local/rvm/rubies/ruby-2.3.0/bin/irb:11:in `<main>'
>>
I tried two different workspaces and effect is the same.My Ruby and Rails versions are:
~/workspace $ ruby -v
ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-linux]
~/workspace $ rails -v
Rails 4.2.2
from my other question I know that word translate is used by many I18N libraries, so it's my only suspect, hence the title of this question. However as a beginner, I don't see any relation.
It is a bug in YARV that was fixed in YARV 2.4.0.
The commit message mentions the following workaround if you don't have YARV 2.4.0:
class << RubyVM::InstructionSequence
def translate; end
undef translate
end
Note that other implementations are not affected, only YARV.
Here is a theory
There is probably a global function translate in your setup
This function is called with an instruction sequence as argument when irb prints the output
Hence when you redefine translate printing the output breaks
The NoMethodError: undefined method does not mean that the method has been undefined globally but that it is being sent to an object that does not understand it
You can test my theory by executing
method(:translate)
If you get a result back then translate is already defined and your must not redefine it!
Now if you want to know which gem defined this function, install pry gem (which is a better irb) and use the $ command to look at the file and source code of that method
# Use this command in pry to see location and source code
$ translate

Getting an undefined local variable error in Ruby when debugging

I have the following script in a file called foo.rb
def foo(msg)
msg
end
def bar
thing = 123
thing
end
debugger
p foo(:hai)
I run the program in debug mode, like so:
ruby --debug -r debug foo.rb
Notice I make sure the stdlib debug is loaded via -r and I also put the ruby environment into debug mode using --debug
So the first output I get is unexpected:
Debug.rb
Emacs support available.
/Users/M/.rbenv/versions/2.1.2/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:57: RUBYGEMS_ACTIVATION_MONITOR.enter
After that, if I press c to 'continue' the program ends with the following error:
Exception `NameError' at foo.rb:10 - undefined local variable or method `debugger' for main:Object foo.rb:10:in `<main>': undefined local variable or method `debugger' for main:Object (NameError)
Can anyone tell me what I'm doing wrong, and how to actually get debug mode to recognise the relevant debugger command (if that's even the correct command to be using; the docs aren't clear at all on this)
Note: I'm not interested in using 3rd party gems in this instance (e.g. pry or ruby-debug). I'm only interested in understanding how to use the stdlib debugger that comes with Ruby
Update
Since this question was answered, I've gone ahead and created a gist for future reference. For anyone stumbling across this thread you might find it useful: https://gist.github.com/Integralist/5658cb218bb50494a1fa
Don't use -r. The entire mechanism by which an interactive debugging sessions is loaded is by the literal line of code require 'debug'.
Your code should look like this:
def foo(msg)
msg
end
def bar
thing = 123
thing
end
require 'debug'
p foo(:hai)
And you should run the program by simply typing ruby <program_name>.rb.

What exception is raised when using + on symbols in Ruby?

Doing the Ruby Koans, in the file about_symbols at line 88, I'm not sure of the answer.
This is the code:
def test_symbols_cannot_be_concatenated
# Exceptions will be pondered further farther down the path
assert_raise(what should i put?) do
:cats + :dogs
end
The point of the Ruby Koans is to learn by reading and trying things out.
Open up a terminal and start irb. Then try using the + operator on two symbols. Check the error you get and substitute it as appropriate in the Koans file.
Assuming that your prompt ends in $, that will look something like this:
$ irb
irb(main):001:0> :cats + :dogs
The answer you need will be clear pretty quickly in the error that irb spits out.
To go through step by step in case your completely new to Ruby you could try:
Open up a terminal
Type irb at your prompt to get to the interactive ruby prompt
This is where you can quickly try out different Ruby things
Type the command in question :cats + :dogs
Review the output which will look like
NoMethodError: undefined method `+' for :cats:Symbol
from (irb):1
The name of the exception thrown which is what you are looking for is the first thing e.g. NoMethodError

Defining an array of arrays as a constant

Im trying to define an array of arrays as a Constant in one of my classes, the code looks like this:
Constant = [[1,2,3,4],
[5,6,7,8]]
When I load up the class in irb I get:
NoMethodError: undefined method `[]' for nil:NilClass
I tried using %w and all that did was turn each one into a string so i got "[1,2,3,4]" instead of [1,2,3,4]
how do I define an array of arrays as a constant?
Im using ruby 1.8.7.
When I define the constant in IRB its fine, but when I load up the class with it in i get an error.
require 'file_with_class.rb'
NoMethodError: undefined method `[]' for nil:NilClass
from ./trainbbcode/tags.rb:2
from /usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
from /usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in `require'
from (irb):1
That file looks like this:
class TBBC
Tags = [[/\[b\](.*?)\[\/b\]/,'<strong>\1</strong>',#config[:strong_enabled]],
...
[/\[th\](.*?)\[\/th\]/,'<th>\1</th>',#config[:table_enabled]]]
The code you showed works just fine. You're definitely not getting that error message for that particular line. The error is caused elsewhere.
And yes, %w creates an array of strings. To create normal arrays use [] like you did.
Edit now that you've shown the real code:
#config is nil in the scope where you use it, so you get an exception when you do #config[:strong_enabled].
Note that inside of a class definition but outside of any method definition #foo refers to the instance variable of the class object, not that of any particular instance (because which one would it refer to? There aren't even any instances yet, when the constant is initialized).
It's a bit strange to use a TitleCase name for a constant. But regardless, it works for me:
$ ruby --version
ruby 1.8.7 (2009-06-12 patchlevel 174) [i686-darwin9.7.0]
$ irb --version
irb 0.9.5(05/04/13)
$ irb
irb(main):001:0> Constant = [[1,2,3,4],[5,6,7,8]]
=> [[1, 2, 3, 4], [5, 6, 7, 8]]
I also tested it in Ruby 1.9.1. Could you be more specific?

How do I drop to the IRB prompt from a running script?

Can I drop to an IRB prompt from a running Ruby script?
I want to run a script, but then have it give me an IRB prompt at a point in the program with the current state of the program, but not just by running rdebug and having a breakpoint.
Pry (an IRB alternative) also lets you do this, in fact it was designed from the ground up for exactly this use case :)
It's as easy as putting binding.pry at the point you want to start the session:
require 'pry'
x = 10
binding.pry
And inside the session:
pry(main)> puts x
=> 10
Check out the website: http://pry.github.com
Pry let's you:
drop into a session at any point in your code
view method source code
view method documentation (not using RI so you dont have to pre-generate it)
pop in and out of different contexts
syntax highlighting
gist integration
view and replay history
open editors to edit methods using edit obj.my_method syntax
A tonne more great and original features
you can use ruby-debug to get access to irb
require 'rubygems'
require 'ruby-debug'
x = 23
puts "welcome"
debugger
puts "end"
when program reaches debugger you will get access to irb.
apparently it requires a chunk of code to drop into irb.
Here's the link (seems to work well).
http://jameskilton.com/2009/04/02/embedding-irb-into-your-ruby-application
require 'irb'
module IRB
def self.start_session(binding) # call this method to drop into irb
unless #__initialized
args = ARGV
ARGV.replace(ARGV.dup)
IRB.setup(nil)
ARGV.replace(args)
#__initialized = true
end
workspace = WorkSpace.new(binding)
irb = Irb.new(workspace)
#CONF[:IRB_RC].call(irb.context) if #CONF[:IRB_RC]
#CONF[:MAIN_CONTEXT] = irb.context
catch(:IRB_EXIT) do
irb.eval_input
end
end
end
This feature is available from Ruby 2.4. You can just use binding.irb
E.g.
require 'irb'
a = 10
binding.irb
puts a
If you run above code, you will get irb console, so that you can inspect values of local variables and anything else that is in scope.
Source: http://blog.redpanthers.co/new-binding-irb-introduced-ruby-2-4/
Ruby commit: https://github.com/ruby/ruby/commit/493e48897421d176a8faf0f0820323d79ecdf94a
Just add this line to where you want the breakpoint:
require 'ruby-debug';debugger
but i suggest use pry instead of irb, which is super handy, insert the following line instead:
require 'pry'; binding.pry
I'm quite late to the game but if you're loading a script from within irb/pry already, a simple raise also works to pop you back out to the irb/pry prompt. I use this quite often when writing one off scripts within the rails console.

Resources