
Security News
Researcher Exposes Zero-Day Clickjacking Vulnerabilities in Major Password Managers
Hacker Demonstrates How Easy It Is To Steal Data From Popular Password Managers
Letters is a little alphabetical library that makes sophisticated debugging easy & fun.
Quick note about Rails: Until I build a Rails-specific gem, I'm changing Letters to patch Object
by default. To only patch core classes, require "letters/patch/core"
. For Rails support, require "letters/patch/rails"
. Make sure to do this after Bundler.require
in application.rb
.
For many of us, troubleshooting begins and ends with the print
statement. Others recruit the debugger, too. (Maybe you use print
statements to look at changes over time but the debugger to focus on a small bit of code.) These tools are good, but they are the lowest level of how we can debug in Ruby. Letters leverages print
, the debugger, control transfer, computer beeps, and other side-effects for more well-rounded visibility into code and state.
If you're using RubyGems, install Letters with:
gem install letters
By default, requiring "letters"
monkey-patches Object
. It goes without saying that if you're using Letters in an app that has environments, you probably only want to use it in development.
With Letters installed, you have a suite of methods available wherever you want them in your code -- at the end of any expression, in the middle of any pipeline. Most of these methods will output some form of information, though there are more sophisticated ones that pass around control of the application.
There are almost 20 Letters methods so far. You can find them in the documentation.
Let's use with the o
method as an example. It is one of the most familiar methods. Calling it prints the receiver to STDOUT and returns the receiver:
{ foo: "bar" }.o
# => { foo: "bar" }
# prints { foo: "bar" }
That's simple enough, but not really useful. Things get interesting when you're in a pipeline:
words.grep(/interesting/).
map(&:downcase).
group_by(&:length).
values_at(5, 10).
slice(0..2).
join(", ")
If I want to know the state of your code after lines 3 and 5, all I have to do is add .o
to each one:
words.grep(/interesting/).
map(&:downcase).
group_by(&:length).o.
values_at(5, 10).
slice(0..2).o.
join(", ")
Because the o
method (and nearly every Letters method) returns the original object, introducing it is only ever for side effects -- it won't change the output of your code.
This is significantly easier than breaking apart the pipeline using variable assignment or a hefty tap
block.
The o
method takes options, too, so you can add a prefix message to the output or choose another output format -- like YAML or pretty print.
Here are the methods, listed with any options that can be passed in to modify their behavior. Some options are available to all methods and are not listed in the table below:
:message (string)
: Print out the specified message as the method is being called.:line_no (boolean)
: Print out the line number where a method is called as it is being called:disable (boolean)
: Disable this method's side effectsYou can easily set these for an entire project using global configuration if you wish (see below).
Letter | Command | Options | Description |
---|---|---|---|
a | Assert | :error_class | asserts in the context of its receiver or Letters::AssertionError |
b | Beep | causes your terminal to beep | |
c | Callstack | prints the current callstack | |
d | Debugger | passes control to the debugger | |
d1/d2 | Diff | :format ,:stream | prints a diff between first and second receivers |
e | Empty | raises a Letters::EmptyError if its receiver is empty | |
f | File | :format , :name | writes its receiver into a file in a given format |
j | Jump | (&block ) | executes its block in the context of its receiver |
k | Kill | :on | raises Letters::KillError at a specified number of calls |
l | Logger | :format , :level | logs its receivers on the available logger instance |
m | Mark as tainted | (true |false ) | taints (or untaints) its receiver |
n | Nil | raises a Letters::NilError if its receiver is nil | |
o | Output | :format , :stream | prints its receiver to standard output |
r | Ri | (method name as symbol) | prints RI documentation of its receiver class |
s | Safety | (level number) | bumps the safety level (by one or as specified) |
t | Timestamp | :time_format | prints out the current timestamp |
See the full documentation for examples and more detailed explanations.
For maximum productivity, you can tune and tweak each Letters method to fit your own tastes. Want to name put files somewhere else? No problem. Don't like YAML? Default f
to use Pretty Print instead! The world of defaults is your oyster.
Letters.config do
f :format => "pp", :name => "my-special-file"
end
You can also change options globally, for methods where the global option is appropriate. For example, if you want every Letters method to print out its line number when called, you can do this for all methods at once:
Letters.config do
all :line_no => true
end
To disable all Letters, for example if you're worried about them getting into a production environment:
Letters.config do
all :disable => true
end
FAQs
Unknown package
We found that letters demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Hacker Demonstrates How Easy It Is To Steal Data From Popular Password Managers
Security News
Oxlint’s new preview brings type-aware linting powered by typescript-go, combining advanced TypeScript rules with native-speed performance.
Security News
A new site reviews software projects to reveal if they’re truly FOSS, making complex licensing and distribution models easy to understand.