When I do something like this in rails:
irb(main):060:0> users = User.where(name: "Joe")
The console will evaluate users
and print it out (maybe with inspect
, or to_s
, I'm not 100% sure). This results in hundreds of lines of output that I don't really want.
I know I can do something like this to prevent the output on one specific line:
irb(main):060:0> users = User.where(name: "Joe"); nil
Because nil
will be evaluated and printed out instead of users
.
I could also turn off all evaluations with:
irb(main):060:0> conf.echo = false
The first solutions is annoying because you have to remember to add that on every line you want to suppress output. And the second is annoying, because sometimes you do want output. Many times you just want to type the name of a variable to have it printed.
Python doesn't seem to have this problem. If I type a = {1: 2}
, the python shell doesn't evaluate a
, it just shows the prompt again. But if I type {1: 2}
or just a
, it does print out the value.
It seems like python's console checks whether there's a left-hand-side of the statement being evaluated to decide whether to print the result or not.
Can something like that be done in ruby's console? So that statements like a = {1 => 2}
are not evaluated, but statements like a
and {1 => 2}
are?
I pushed this merge request to the irb repo, perhaps it'll be accepted and then there will be a way: https://github.com/ruby/irb/pull/12 .
A version of the MR referenced below was merged to irb, but tweaked a few times since then. So to get the behavior you want it depends on the irb version:
If you have at least 1.2.0
, but less than 1.2.6
: the default behavior is to not print anything for assignment statements. You have to set IRB.conf[:ECHO_ON_ASSIGNMENT] = true
if you want the old behavior (of always printing everything).
If you have 1.2.6
, the default value for ECHO_ON_ASSIGNMENT
was changed to true
, and a new config value: OMIT_ON_ASSIGNMENT
was added which will truncate long output for assignment statements, it defaults to true
. So you have to set IRB.conf[:ECHO_ON_ASSIGNMENT] = false
if you don't want anything to be printed for assignment statements. You have to set IRB.conf[:OMIT_ON_ASSIGNMENT] = false
if you want the old behavior (of always printing everything).
If you have 1.2.7
or above, OMIT_ON_ASSIGNMENT
was removed in favor of letting ECHO_ON_ASSIGNMENT
accept true
, false
, or :truncate
, with the default value being :truncate
. A value of true
will print everything for assignment statements, false
will print nothing, and :truncate
will print a truncated version (like setting OMIT_ON_ASSIGNMENT
to true
in 1.2.6
).
Note that the versions above versions of the irb gem, not ruby versions (even though irb
is included in ruby's standard library). You can check what version of irb
you have by looking at IRB::VERSION
. Very old versions of irb
don't set this constant, so if it's missing, you definitely have a version lower than 1.2.0
.
Until this pull request (or one like it) is merged, you can put the following into your ~/.irbrc
file:
require 'ripper'
module IRB
class Irb
ASSIGNMENT_NODE_TYPES = [:assign, :opassign, :massign]
def assignment_expression?(line)
ASSIGNMENT_NODE_TYPES.include?(Ripper.sexp(line)&.dig(1,-1,0))
end
def output_value # :nodoc:
return if assignment_expression?(@context.last_line)
printf @context.return_format, @context.inspect_last_value
end
end
class Context
attr_accessor :last_line
def evaluate(line, line_no, exception: nil) # :nodoc:
@line_no = line_no
@last_line = line
if exception
line = "begin ::Kernel.raise _; rescue _.class; #{line}; end"
@workspace.local_variable_set(:_, exception)
end
set_last_value(@workspace.evaluate(self, line, irb_path, line_no))
end
end
end
Note that since this monkey-patches IRB::Irb
and IRB::Context
, there's no guarantee that it will be compatible with future releases.