Rerun only failed tests
When running tests in Elixir, if you only want to rerun the failed tests, just pass in --failed
mix test --failed
When running tests in Elixir, if you only want to rerun the failed tests, just pass in --failed
mix test --failed
Today I learned you can see which processes have a file open with fuser
. For example, if I wanted to see what process was writing to log/development.log
in my rails app, I'd run
$ fuser log/development.log
log/development.log: 76170
So the process with PID 76170 has the file open. Running ps
will show me the process details:
$ ps 76170
PID TT STAT TIME COMMAND
76170 s008 S+ 0:02.86 ruby bin/rails console
Turns out I had a rails console
running!
You could also turn this into a one-liner with xargs
:
$ fuser log/development.log | xargs ps
Yesterday I learned (YIL?!) how to override instance methods within pry
. But what if you like the change and want make it more permanent? Typically what I would do is edit the appropriate file in my editor, and either reload!
within pry
or restart the session.
I learned you can also edit the code directly from within pry
- if I want to edit the User
class, I can run edit User
and pry will open the file that defines User
in my $EDITOR
((n)vim, natch). When you close the file, you'll be dropped back into your pry
session and the code will be reloaded (including any instances of the class you already initialized in your session).
class User
def name = "tony"
end
pry(main)> me = User.new
pry(main)> me.name
# => "tony"
pry(main)> edit User # and let's say we edit name to return 'not-tony'
pry(main)> me.name
# => "not-tony"
pry(main)> User.new.name
# => "not-tony"
Today I learned how to run jest sequentially by just adding --runInBand
or -i
to the jest command. This way I can investigate which test execution is trowing some warnings in the codebase I am working on.
Today I learned you can override methods on an object from within pry
! Super helpful if you want to test something out but not change it in code yet. It's important to note this only overrides at the instance level, not the class level, so other instances won't be affected.
class User
def name = "tony"
end
pry(main)> me = User.new
pry(main)> me.name
# => "tony"
pry(main)> def me.name = "who now?"
pry(main)> me.name
# => "who now?"
pry(main)> other_me = User.new
pry(main)> other_me.name
# => "tony"
the uptime
command tells you how long your computer has been running since its' last bootup. S/O Craig
Vim macros are great, but they can become tedious if you need to repeat the macro over and over again on multiple lines. norm
comes in super handy in these cases! You can use it to operate on every line, or you can apply it to a visual select range.
* one,
* two,
* three,
* four,
Given a file like above and I want to change just the lines with text two
, three
, by replacing the *
with a -
and change the ending comma to a semicolon, I can visual select those lines (Shift + V
), enter command mode with :
and run:
:'<,'>norm 0s-^[$s;
Let's break it down:
'<,'>
is the visual selection range norm
is the norm
command 0s-
replaces the first character of the line with -
^[
is actually not typed directly but is an escaped ESC
char inserted by Ctrl + V, Esc
. This allows you to re-enter command mode inside norm mode. $s'
replaces the last character of the line with ;
After running the command, the file should look like:
* one,
- two;
- three;
* four,
Req has a built-in for handling some auth mechanisms, such as Basic Auth, Bearer, and netrc.
You can send the auth as a tuple, where the first element is the type and the second is the credential -
Req.post("https://example.com", json %{foo: "bar"}, auth: {:basic, "user:password"})
You can use Ctrl
+ Up Arrow
to quickly open Mission Control on OSX.
I often use my Mac in clamshell mode and I forget that I can do this to see all my desktops at the top. You can also use Ctrl
+ Right Arrow
and Ctrl
+ Left Arrow
to alternate between your other open desktops.
Due to ActiveRecord single table inheritance in Rails, the the attribute type
is a reserved word by default. However, I like to use type
when STI is not in the picture. We can do this per model by setting inheritance_column
. Much like most things in Rails there is a sane default for convention but can be overrdiden. In this case we will be 'disabling' is by setting to nil
class Foo < ApplicationRecord
self.inheritance_column = nil
end
Now you're free to use the type
column as wish.
Have you ever needed to debug a production JavaScript issue but couldn't modify the source code directly? Chrome's Overrides feature is here to save the day! This powerful tool allows you to persist JavaScript changes between page reloads, even when you don't have direct access to the original source files.
Here are the steps:
You can reload the page and your change will be persisted locally and executed in the browser.
Remember to delete your overrides once you're done.
Happy debugging! 🛠️
In addition to the built in search shortcuts in firefox, you can also add custom shortcuts in the settings.
This lets you override your default search engine by prepending a keyword in your address bar (like @google
, @duckduckgo
, @kagi
). It's a quick shortcut if you want to search for something on a specific site. The wikipedia one (@wiki
) is especially neat in that it'll take you straight to the wikipedia page if there's a direct hit, no results page you need to go through first.
I just found out that since elixir 1.15.0 we can call DateTime utc now and get that response truncated in seconds already:
iex> DateTime.utc_now(:second)
~U[2025-06-03 13:27:44Z]
and this has the same effect of what I used to do until now:
iex> DateTime.utc_now() |> DateTime.truncate(:second)
~U[2025-06-03 13:27:45Z]
Firefox has built in search shortcuts in the address bar, making it easy to search through your bookmarks, tabs, history and actions you can perform.
In the address bar (which you can focus with Cmd + L
), including the following characters in your search will:
*
search within your bookmarks %
search within your tabs ^
search within your history >
search within actions - like Manage bookmarks, View downloads, Take a screenshot
The neat thing is you don't need to start your search with the shortcut, you can add it anywhere. So you can start typing something in the address bar, remember you visited the page yesterday, and add ^
at the end to filter down to your history.
This is not pretty new but I just found out, so github has a few slash commands which are pretty handy, chiefly the alert
and table
one for me.
The table one asks you how many rows and columns you want and it scaffolds the table markdown for you:
Did you know that pluck
was not just available in ActiveRecord
? Turns out Rails added it to Enumerable
so you can use it on most collections.
But wait...
Before you go and do something like this:
all("nav a").pluck(:text)
Beware that pluck
's implementation does a key lookup on the object being enumerated (reference). So in this particular case because text
is a method on these Capybara
elements you'd need to use map
all("nav a").map(&:text)
But you could use it for things that respond to hash/key lookup syntax like:
all("nav a").pluck(:href)
If you do option + click
in VS code, a multi-cursor will be inserted at the position of your mouse.
Using VS code's command palette, Cmd+Shift+P, You can transform highlighted text to camel case
You can also transform to most other cases.
The scrollHeight
Element property gives you an elements entire scrollable content height, meaning it accounts for the overflowed content not visible on the screen.
You can run rails stats
to print out statistics around lines of code,
classes, methods, code to test ratio, etc for your rails app. It'll print out a
table like this:
(Don't mind the code to test ratio...it's a proof of concept app 😅)
h/t Joel Hawksley, I learned about this from the excellent talk he gave at Chicago Ruby last week.
Today I learned you can write nested expectations in rspec
. I find this is approach useful with writing request-style tests where I want to ensure the request returned successfully and also ensure the expected effects happened.
it "creates the post" do
expect {
expect(request.response_code).to eq(200)
}.to change { Post.count }.by(1)
end
If either the response is not 200
, or the Post
count doesn't change, then the test fails.
There is a gotcha that I run into when I build these tests iteratively - first the inner expectation on it's own, wrap it in the outer block, and then add the outer matcher. If you wrap the inner request in an expect block, but don't have any assertions on that block, it will always pass - because we're not matching against anything.
RSpec.describe do
# ❌ - as expected
it do
expect(true).to eq(false)
end
# ❌ - as expected, outer expectation passes but inner fails, so test fails
it do
expect {
expect(true).to eq(false)
}.to not_change { 0 }
end
# ✅ - :-? watch out for this one, even though the inner expectation fails, test passes
it do
expect {
expect(true).to eq(false)
}
end
end
Ecto.Query has a function called exclude
you can call it to remove previous parts of a query that have already been defined
query = from(u in User,
where: u.email == "jack@example.com",
select: u.email
query
|> exclude(:where)
#=> will return the %Ecto.Query{} expression without the where clause
Enum.random
is a simple way to select a random element of an Elixir enum.
[1, 2, 3]
|> Enum.random()
# => who knows?? either 1, 2, or 3
Due to github permissions on projects that I am working on I wanted to switch which user I am connecting to github on a per project base. I also want to keep using ssh keys for that, so I found out that we can have 2 different ssh keys pointint to the same domain, we just had to do a simple twich:
Host github.com
HostName github.com
IdentityFile ~/.ssh/id_ed25519
Host vinny.github.com
HostName github.com
IdentityFile ~/.ssh/vinny_id_ed25519
So I end up creating 2 ssh keys, 1 per user that I need to access on github. Then left the original ssh key as regular github.com
domain, so no changes there, and on the projects that I need to access with the other user I had to clone with:
git clone git@vinny.github.com:MyOrganization/my-project.git
And if you have an exisintg project that you want to move to this new github user you'll have to change the remote on that:
git remote remove origin
git remote add origin git@vinny.github.com:MyOrganization/my-project.git
By the way, as you are changing which keys to use with an existing domain, you may have to restart the ssh-agent
in order for this to work:
eval "$(ssh-agent -s)"
Did you know that you can use pattern matching headers with anonymous functions in elixir? It works like this:
anon = fn
{:ok, value} -> "Got value: #{value}"
_ -> "Doing something else"
end
# IO.puts anon.({:ok, 42}) # => "Got value: 42"
# IO.puts anon.(:ok) # => "Doing something else"
We had a situation that we wanted to guarantee that an "index" page under a tab navigation was always there, this way we could go back using the navigation to the index page, even if the user entered to that tab navigation via another screen. I learned that we can use withAnchor
prop in conjunction with the unstable settings initialRouteName
. This worked really fine and now our back buttons always go to each tab's index screens.
Check this out Expo Router navigation patterns
You can make text unable to be highlighted by using the tailwind class select-none
<div class="select-none">
You can't highlight/select me
</div>
I'm on a bit of a random kick lately. Today I learned you can randomly sort rows returned in a query using Postgres' random()
function.
SELECT *
FROM users
ORDER BY random()
What it does is it calculates a random value for each row returned, and then orders by that calculated value. If the query returns a lot of rows this can be slow, so probably more useful for exploration or one-offs not necessarily for production uses.
When rescuing exceptions with the intent to reraise them after doing some logic, you don't need to pass the original exception to the raise
method:
begin
# ...
rescue
puts "Something went wrong"
raise # will raise the original exception
end
TIL about the RAILS_DEVELOPMENT_HOSTS
env variable. This adds the hosts specified to your environment, so that you don't have to manually update config.hosts
.
Just start your server like so
$ RAILS_DEVELOPMENT_HOSTS="my-url.ngrok-free.app" bin/rails s
h/t Matt Polito
Today I Learned about jot
, a command line utility that prints sequential or random data. Let's focus on the sequential bit.
jot
takes arguments for reps
, begin
and end
. So if we wanted to print the integers from 1 to 10, we'd do:
$ jot - 1 10
1
2
3
4
5
6
7
8
9
10
Which is neat, but only so cool. What if we wanted to print 21 evenly spaced numbers between -1 and 1? That would be cooler:
$ jot 21 -1 1.00 #the 1.00 tells the output to be float, not int
-1.00
-0.90
-0.80
-0.70
-0.60
-0.50
-0.40
-0.30
-0.20
-0.10
-0.00
0.10
0.20
0.30
0.40
0.50
0.60
0.70
0.80
0.90
1.00
You can even print all the ASCII characters with:
jot -c 128 0
1
2
3
4
5
6
7
8
9
:
;
<
=
>
?
@
A
B
C
...
Say you have a variable set in a shell script:
export testPath='/Users/mary/code/thingy.rb'
You can echo that variable as usual:
echo $testPath
# /Users/mary/code/thingy.rb
But you can also get substrings of that variable as you echo it, using substring extraction. The substring extraction syntax is ${variable:offset:length}
echo ${testPath:11}
# /code/thingy.rb
echo ${testPath:12:4}
# code
You can also change the prefix (${variable#prefix}
) and suffix (${variable%suffix}
):
echo ${testPath#/Users/mary/code/}
# thingy.rb
echo ${testPath%.rb}
# /Users/mary/code/thingy
You can sort
to sort text in a file or STDIN. But what if you want to embrace the chaos and sort randomly? Turns out, there's a few ways to do that.
sort -R file.txt
- sort
's -R
option does a random sort rather than lexicographically. The caveat here is if you have duplicates, they will be grouped together in the resulting output. shuf file.txt
- shuf
is a standalone utility to generate random permutations. Read their man pages to learn more!
easings.net has a handy table for visualizing easing functions for animation curves.
By default, if you make a change to a belongs_to
associated model and save the parent model, the associated model won't be saved. This is probably a good default, but it is overridable with the :autosave
option.
class Book < ApplicationRecord
belongs_to :author
end
book = Book.first
book.author.name # => "J.R.R. Tolkein"
book.author.name = "John Tolkein"
book.save
book.reload
book.author.name # => "J.R.R. Tolkein"
But we can change this behaviour by setting :autosave
to true.
class Book < ApplicationRecord
belongs_to :author, autosave: :true
end
book = Book.first
book.author.name # => "J.R.R. Tolkein"
book.author.name = "John Tolkein"
book.save
book.reload
book.author.name # => "John Tolkein"
While this is off by default for belongs_to
associations, has_one
and has_many
associations have :autosave
true because the foreign keys are on the associated records to ensure those FKs are kept up to date.
PostgreSQL has a function called jsonb_to_recordset
that will return your jsonb data as if it were rows in the database.
Say we have the following example table:
create table notes (title varchar, bullets jsonb);
insert into notes (title, bullets)
values ('Inspection', '[{"field": "Tires", "measured": "Tread Height", "value": "3mm"},{"field": "Brakes", "measured": "Caliper Boot", "value": "cracked"}]');
To use the jsonb_to_recordset
function, we can do the following:
select title, field, measured, value
from notes
cross join lateral jsonb_to_recordset(notes.bullets)
as temp(field varchar, measured varchar, value varchar);
The function gives us the following output:
title | field | measured | value
------------+--------+--------------+---------
Inspection | Tires | Tread Height | 3mm
Inspection | Brakes | Caliper Boot | cracked
One of the nice things about working with Visual Studio based text editors is its multi-cursor abilities. For those who don't know, you can highlight a word and pressing CMD
+D
you can place another cursor at the next occurrence of that string.
This is helpful for making a lot of changes at once. Here's an example where we can fix a typo that was made all throughout a file:
typo = getTypo
if(typo)
# do something with the typo
else
# do something else
end
def getTypo()
typo
end
Well, what if we want a cursor at every occurrence of a typo, but we want a faster way than pressing CMD
+D
a bunch of times?
TLDR
Just highlight the word you want to grab and press CMD
+Shift
+L
and it will grab all occurrences found in that file. (Just be careful and make sure that's what you actually want!)
In vim :e
edits the current file (reloads from disk), which is useful if the file has been changed outside of vim and you want to load those changes into your buffer in vim.
I ran into a scenario where I ran a formatter outside of vim, and wanted to reload all files open in buffers in my vim session. I took a guess that :ea
would edit all (like :wa
writes all, :qa
quits all) - but alas, swing and a miss.
The way to do this is with :bufdo e
. bufdo
executes the command - in this case e
- in each buffer in the buffer list.
Reading man pages in (n)vim is my new favorite way to read man pages. (n)vim gives you syntax highlighting, plus you can follow the links with Shift + K
(yes, there are links between man pages - I never knew!).
You can override the default pager for man
by setting the MANPAGER
environment variable (the default is less -sR
) - per the nvim help page, you can use nvim with export MANPAGER='nvim +Man!'
.
Happy manual reading!
h/t Josh Branchaud, the TIL GOAT.
I found out that Keyword.validate/2 is a great way to guarantee that a function would be called with the right keyword options. Check this out:
def do_something(%User{} = user, opts \\ []) when is_list(opts) do
{:ok, opts} = Keyword.validate(opts, [:preload])
preload = Keyword.get(opts, :preload, [])
#...
end
Here's some interesting cases:
# fails if you pass an invalid option
Keyword.validate([one: "1", two: "2"], [:one])
# => {:error, [:two]}
# fails if you pass a valid option that is not expected that many times
Keyword.validate([one: "1", one: "again"], [:one])
# => {:error, [:two]}
# it can set default values
Keyword.validate([one: "1"], [:one, two: "5"])
# => {:ok, [two: "5", one: "1"]}
# it succeeds if you pass the right options
Keyword.validate([one: "1", two: "2"], [:one, :two])
# => {:ok, [two: "2", one: "1"]}
The delayLongPress
prop on the react native pressable component allows you to specify a delay in milliseconds before the onLongPress
callback prop is executed. Allowing you to control exactly how long a user should press on the element before receiving feedback etc.
If you want to prevent your display from going to sleep while you are doing something that doesn't require input, you can use caffeinate -d
For me this was useful when running a longer script that I wanted to keep an eye on while I was debugging. By running caffeinate -d
in a terminal I was able to prevent the display from sleeping, saving me from pressing a button or moving the mouse all the time.
Today I learned about the unary plus (+
) operator. It attempts to convert its operand into a number, so it's basically a shorthand for Number()
(and uses the same rules around number coercion).
+"7"
// 7
+5
// 5
+true
// 1
+false
// 0
+null
// 0
+undefined
// NaN
+[]
// 0
Today I learned about the -C
flag for git commit
. It's used in Hashrocket's dotmatrix in our git cheddar
alias - git commit --amend -CHEAD
, but I never actually dug into what it does.
From the manual:
-C <commit>, --reuse-message=<commit>
Take an existing commit object, and reuse the log message and the authorship information (including the timestamp) when creating the commit.
Important to note, -C
doesn't open your editor to edit the message, so it's great if you don't need to edit the existing message (if you do want to edit, lowercase -c
will open your editor with the existing message).
-CHEAD
....ohhhh that's why it's called cheddar
🤯
You can set the dimensions of the simulator window to be the exact physical size of the simulated device on the xcode IOS simulator.
Window -> Physical Size or Command + 1
Today I learned a way to view all the enums defined on an ActiveRecord Model.
Suppose I have a class Post
with enums status
and category
:
class Post < ApplicationRecord
enum status: [:draft, :published]
enum category: [:ruby, :rails, :lord_of_the_rings]
end
I can view the enum values for statuses with Post.statuses
and category with Post.categories
, but what if I want to see all the enums on Post
? defined_enums
will do that:
Post.defined_enums
# => {"status"=>{"draft"=>0, "published"=>1}, "category"=>{"ruby"=>0, "rails"=>1, "lord_of_the_rings"=>2}}
You can of course key in to each enum here too:
Post.defined_enums["status"]
# => {"draft"=>0, "published"=>1}
Kamal, the default deployment tool for Rails, has some really great features. One that I just discovered today is kamal secrets
.
You can use this utility to expand sensitive credentials from external sources during deployment. Out of the box, it supports 1Password, Bitwarden (and Secrets Manager), LastPass, AWS Secrets Manager, Doppler, and GCP.
You can run the command for SECRETS
from the .kamal/secrets
file manually to test everything out.
A pre-req for using 1Password is that you will need to install the OP CLI and login to your vault:
brew install 1password-cli
op signin
Next you'll need your account id. You can get that with -
op whoami
Then verify you can read your secrets. The output of the command inside the $(...)
is a stringified JSON -
SECRETS=$(kamal secrets fetch --adapter 1password --account op_account_id --from "op://Example/ApiKeys" KAMAL_REGISTRY_PASSWORD)
The output will look something like this -
\{\"Example/ApiKeys/KAMAL_REGISTRY_PASSWORD\":\"xxxxxxxxxxxxx\"\}
The last part is expanding this. You can pass this JSON string to kamal secrets extract
to extract the value from the key in the JSON.
kamal secrets extract KAMAL_REGISTRY_PASSWORD ${SECRETS}
In MacOS you can go the lock screen quickly using the keyboard by pressing:
CTRL
+ CMD
+ Q
You can change the context of your console session by using the cd
just like you would change the context of your directory.
Here is an example.
# Grab an object, in our example a customer.
c = Customer.all.sample
# Now, 'cd' in to that object.
cd c
# From here you will notice that we are now within
# the context of our object and can call methods on it directly.
pry(<Customer>):1> first_name
=> "Peter"
pry(<Customer>):1> last_name
=> "Parker"
I found this cool tip, as well as some others in this awesome blog post.
It feels like there are an absurd number of options with the built in macOS screenshot tool.
We've seen before you can screenshot the entire screen or select a rectangle and save them as a file or to your clipboard.
Today I Learned there's an option to select an individual window and screenshot the entire window.
You can do this by hitting CMD + shift + 4
(with or without ctrl
), then tap space
. The cursor will change to a camera, and then you can click on the windows you wish to screenshot!
Looks much better than when I try to crop by hand.