Is there a way to achieve grep like functionality on output inside the Rails Console Is there a way to achieve grep like functionality on output inside the Rails Console ruby ruby

Is there a way to achieve grep like functionality on output inside the Rails Console


Yes, you can. The method is called gr... wait for it ...ep. Ruby's grep works on String, Array and many other built-in objects. For example to get all to_xxx methods of a number, just do:

 1.methods.grep(/to_/)


I had the same question and wasn't very satisfied with the somewhat snarky response from ream88, so I decided to take a crack at it.

# Allows you to filter output to the console using grep# Ex:#   def foo#     puts "Some debugging output here"#     puts "The value of x is y"#     puts "The value of foo is bar"#   end# #   grep_stdout(/value/) { foo }#   # => The value of x is y#   # => The value of foo is bar#   # => nildef grep_stdout(expression)  # First we need to create a ruby "pipe" which is two sets of IO subclasses  # the first is read only (which represents a fake $stdin) and the second is  # write only (which represents a fake $stdout).  placeholder_in, placeholder_out = IO.pipe  # This child process handles the grep'ing.  Its done in a child process so that  # it can operate in parallel with the main process.  pid = fork {    # sync $stdout so we can report any matches asap    $stdout.sync    # replace $stdout with placeholder_out    $stdin.reopen(placeholder_in)    # we have to close both placeholder_out and placeholder_in because all instances    # of an IO stream must be closed in order for it to ever reach EOF.  There's two    # in this method; one in the child process and one in the main process.    placeholder_in.close    placeholder_out.close    # loop continuously until we reach EOF (which happens when all    # instances of placeholder_out have closed)    read_buffer = ''    loop do      begin        read_buffer << $stdin.readpartial(4096)        if line_match = read_buffer.match(/(.*\n)(.*)/)          print line_match[1].grep(expression)  # grep complete lines          read_buffer = line_match[2]           # save remaining partial line for the next iteration        end      rescue EOFError        print read_buffer.grep(expression)  # grep any remaining partial line at EOF        break      end    end  }  # Save the original stdout out to a variable so we can use it again after this  # method is done  original_stdout = $stdout  # Redirect stdout to our pipe  $stdout = placeholder_out  # sync $stdout so that we can start operating on it as soon as possible  $stdout.sync  # allow the block to execute and save its return value  return_value = yield  # Set stdout back to the original so output will flow again  $stdout = original_stdout  # close the main instances of placeholder_in and placeholder_out  placeholder_in.close  placeholder_out.close  # Wait for the child processes to finish  Process.wait pid  # Because the connection to the database has a tendency to go away when calling this, reconnect here  # if we're using ActiveRecord  if defined?(ActiveRecord)    suppress_stdout { ActiveRecord::Base.verify_active_connections! }  end  # return the value of the block  return_valueend

The obvious drawback of my solution is that the output is lost. I'm not sure how to get around that without calling yield twice.

EDIT I've changed my answer to only call fork once, which allows me to keep the output of the block and return it at the end. Win.

EDIT 2 You can get all of this functionality (and more!) in this gem now https://github.com/FutureAdvisor/console_util