Today I Learned

A Hashrocket project

Ready to join Hashrocket? Find Openings here and apply today.

How to restrict visually selected replace

Make a visual selection in vim, then type :. You can do a search and replace by the normal means:

:'<,'>s/something/something else/g

The only problem with this is that it defaults to the whole line. So if, for example, you are trying to replace the / character within a selection on a line of an HTML or template file, this will screw up the closing tag of that line.

The trick here is to use %V in the matching portion.

:'<,'>s/\%Vsomething/something else/g

This restricts the match criteria to just the selection! Checkout :help %V.

Parse a Query String in Ruby

If you ever need to parse a query string in Ruby - or Rails, Rack has a convenient utility to do just that. parse_nested_query will parse from a string to a hash:

Rack::Utils.parse_nested_query("&sort_dir=asc&sort_by=date_created&filter_by=lead")

=>  {"sort_dir"=>"asc", "sort_by"=>"date_created", "filter_by"=>"lead"}

You can also go the opposite way with build_nested_query and generate a query string:

Rack::Utils.build_nested_query({"sort_dir"=>"asc", "sort_by"=>"date_created", "filter_by"=>"lead"})

=>  "sort_dir=asc&sort_by=date_created&filter_by=lead"

https://www.rubydoc.info/gems/rack/Rack/Utils

Postgres regex matching with squiggles

Postgres supports POSIX regex pattern matching using the squiggle (~) operator

-- Check for a match
select 'wibble' ~ 'ubb';
-- returns false
select 'wibble' ~ 'ibb';
-- returns true

-- Case insensitive match checking
select 'wibble' ~ 'IBB';
-- returns false
select 'wibble' ~* 'IBB';
-- returns true

-- Check for no match
select 'wibble' !~ 'ibb';
-- returns false
select 'wibble' !~ 'ubb';
-- returns true

Full postgres pattern matching documentation can be found here

Find the position of a substring in postgres

Postgres has a strpos function for finding the position of a substring in a given string:

select strpos('wibble', 'ibb');

The function returns an integer representing the location of the substring in the provided string, or a 0 if the substring cannot be found in the provided string (the locations are 1-based indexes, so you don’t have to worry about collisions!).

Hibernating a GenServer

I was reading a great blog post from @cloud8421 this morning and I learned that Elixir GenServer has the capability to hibernate itself, which it means that it halts the continuous looping if there’s no incoming message and it runs a garbage collection to release some memory generated by that process.

Use that with moderation, and it’s always nice to evaluate if we really need to put a GenServer to hibernate, but in some cases it’s very handy.

Use the <datalist> element for input suggestions

HTML5 has a <datalist> element which you can you use to create suggestions for inputs.

Just specify the list attribute on your input, whose value should correspond to the id of the datalist, and then populate your datalist with options:

<input list="programming-languages" id="programming-language-choice" name="programming-language-choice" />

<datalist id="programming-languages">
    <option value="Ruby">
    <option value="Elixir">
    <option value="Java">
</datalist>

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist

How to force reload associations in Ecto

Ecto by default doesn’t load associations and you have to explicitly call preload:

id = 1
user = Repo.get(User, id) |> Repo.preload(:posts)

If you call preload again on the same user, Ecto won’t make the SQL query again because the association is already loaded:

user = user |> Repo.preload(:posts)

But in some cases you do want to reload a preloaded association then you can use force: true:

user = user |> Repo.preload(:posts, force: true)

Disable capture in Elixir Regex

Today I came across a regex that had to use the ( parenthesis to match a sequence of chars but I wanted just to match them, so I’d love if I could ignore that piece from the “capture” part.

So I learned that we could use ?: in the beginning of the ( and that would turn the capture off for that piece. Check this out;

iex> Regex.scan(~r/aa(bb)(?:cc|CC)/, "aabbccdd aabbCCdd")
[["aabbcc", "bb"], ["aabbCC", "bb"]]

In this case I am matching and capturing the bb sequence and I am matching but not capturing the cc|CC sequence options.

Set JSON.parse returned object and array classes

By default, the Ruby JSON.parse method returns a ruby Hash for any json object, and a ruby Array for any json array.

However, you can customize the returned object classes using the object_class and array_class options:

source = JSON.dump({ wibble: "wubble", data: [1,2,3] })

result = JSON.parse(
  source, 
  object_class: OpenStruct,
  array_class: Set
)
# => #<OpenStruct wibble="wubble", data=#<Set: {1, 2, 3}>>

result.data # => #<Set: {1, 2, 3}>
result.wibble # => "wubble"

Add a folder to git with exceptions

Given this folder structure:

app
├── bin
│  └── parse-ansi-codes.rs
├── Cargo.lock
├── Cargo.toml
├── README.md
├── src
│  ├── cursor.rs
│  ├── lib.rs
│  └── style.rs
├── target
│  └── debug
└── test

I can add the entire app directory to git, while ignoring the bin folder:

$ git add . ':!bin'

rspec should receive thrice

rspec has a #thrice method for testing receive counts:

describe Account do
  context "when opened" do
    it "logger#account_opened was called once" do
      logger = double("logger")
      account = Account.new
      account.logger = logger

      logger.should_receive(:account_opened).thrice

      account.open
      account.open
      account.open
    end
  end
end

Replace multiple characters in ruby strings

Ruby String#tr allows you to replace characters or patterns in strings:

irb(main):001:0> "I love coffee".tr("love", "😍")
=> "I 😍😍😍😍 c😍ff😍😍"

Compare with #gsub:

irb(main):001:0> "I love coffee".gsub("love", "😍")
=> "I 😍 coffee"

If your pattern arg to gsub is only one character consider using #tr, but beware of multi-length from_str arg to #tr

Split text in postgres

You can split text in postgres

select email from users;
bob@example.com
mary@example.com
select split_part(email, '@', 1) from users;
bob
mary
select split_part(email, '@', 2) from users;
@example.com
@example.com

Which can be helpful when sanitizing data:

update users
  set email = split_part(email, '@', 1) || '@example.com';

List cli xcodebuild archives in Xcode's organizer

When using a Makefile to build Xcode applications, it’s nice to have the archives listed in the Organizer window, for easy distribution. This can be accomplished with the -archivePath flag, using a specific directory:

BOB_THE_BUILD_DIR="~/Library/Developer/Xcode/Archives/$(date +%Y-%m-%d)"
ARCHIVE_PATH="$BOB_THE_BUILD_DIR/MyApp-$(date|md5).xcarchive"

xcodebuild -scheme MyApp -workspace "MyApp.xcworkspace" archive -configuration release -archivePath "$ARCHIVE_PATH"

Preview ffmpeg video filters without re-encoding

I was playing around with some ffmpegfilters, like cropping, scaling and overlays and I was tired of waiting for the video to be fully re-encoded in order to see the changes.

ffmpeg -i video.mp4 -vf "crop=in_w:in_h/2:0:0" -c:a copy output.mp4

I’m glad that this is not a problem because you can use ffplay to preview the changes instantly without having to wait:

ffplay -i video.mp4 -vf "crop=in_w:in_h/2:0:0"

How to conditionally add a value in array literals

I really like declarative things. It’s probably why I like React, and really dig functional programming approaches. So when I’m writing Ruby, sometimes I find myself wanting to delcare some array of values to use in a map, reduce, or each. The problem is, sometimes I only want a particular value give a condition. One pattern that I’ve started to try on for size is

def things
  [something, (something_else if reasons)]
end

Then, you can use it like so:

things.compact.map(&:cool_method)

The conditional will evaluate and leave a nil in the array, which isn’t my favorite. However, I’ve found that this is a very useful pattern for simplifying certain methods.

When to set `inverse_of` in Rails AR

Rails ActiveRecord does not auto infer bi-directional associations if some of the associations contains a scope or any of the following through or foreign_key options.

class Author < ApplicationRecord
  has_many :books
end

class Book < ApplicationRecord
  belongs_to :writer, class_name: 'Author', foreign_key: 'author_id'
end
irb> a = Author.first
irb> b = a.books.first
irb> a.first_name = 'David'
irb> a.id = b.writer.id
=> true
irb> a.object_id = b.writer.object_id
=> false
irb> a.first_name == b.writer.first_name
=> false

To solve this issue we should use inverse_of option, check this out:

class Author < ApplicationRecord
  has_many :books, inverse_of: 'writer'
end

class Book < ApplicationRecord
  belongs_to :writer, class_name: 'Author', foreign_key: 'author_id'
end
irb> a = Author.first
irb> b = a.books.first
irb> a.first_name = 'David'
irb> a.id = b.writer.id
=> true
irb> a.object_id = b.writer.object_id
=> true
irb> a.first_name == b.writer.first_name
=> true

Github Resolving Git Conflicts

Today I tried out Github to Resolve Git Conflicts of an open PR. I noticed that Github has this gray button Resolve conflicts:

image

Then it drives me to a managing conflicts page with a simple editor where I could manually choose and edit the conflicts:

image

After my editing is done I can Mark as resolved:

image

And finally I can Commit merge:

image

Wait, what? oh no, I know that merging is the easiest way to solve conflicts as you solve all conflicts once, no matter how many commits your branch has, but to be honest I did not like that. I put some small effort to keep my git history clean and I really avoid merge commits as they are not necessary in general. I tend to keep a single history line on my git repos in the main branch, most of the times at least.

I guess that it is what it is, every time we use a tool to “simplify” the work we are giving up a bit of control on how the things are executed, right?

So here’s the resolve of Github’s solving git conflicts flow:

image

Preloading data for Phoenix LiveView components

One of the most common problems in web development is N+1. Graphql has taught me the DataLoader pattern and since then I never had to worry about N+1 as long as I kept using that pattern.

With Phoenix LiveView you don’t need to think about APIs anymore but I’m glad that it has support for preloading data kind of the same way as if it was a DataLoader. You can define a preload function that will receive a list of all the assigns so you can preload all the data needed for multiple components in one single batch before they are mounted. Here is the sequence of a component lifecycle:

preload(list_of_assigns) -> mount(socket) -> update(assigns, socket) -> render(assigns)

On this example only one SQL query is made to load all products by id:

@impl true
def preload(list_of_assigns) do
  product_ids = Enum.map(list_of_assigns, & &1.product_id)

  products =
    from(p in Product, where: p.id in ^product_ids, select: {p.id, p})
    |> Repo.all()
    |> Map.new()

  Enum.map(list_of_assigns, fn assigns ->
    Map.put(assigns, :product, products[assigns.product_id])
  end)
end

Conditionally Render Rails Links with `link_to_if`

ActionView::Helpers contains some really handy helpers for conditionally rendering links. For example, the link_to_if method will render the link if the given condition is met; otherwise it renders just the text.

<%= link_to_if(current_user.present?, "Admin Panel Tools", admin_tools_path) %>

When current_user.present? is true, yields the following HTML:

<a href="/admin_tools">Admin Panel Tools</a>

But when current_user.present? is false, yields the following:

Admin Panel Tools

https://api.rubyonrails.org/v6.0.2.1/classes/ActionView/Helpers/UrlHelper.html#method-i-link_to_if

Note, there are also methods for link_to_unless and link_to_unless_current

Elixir Supervisor default child_spec

When using Supervisor elixir already declares a child_spec/1 for us with the right type: :supervisor. The generated code will be something like:

defmodule MyApp.MySupervisor do
  use Supervisor, opts
  
  ...

  def child_spec(init_arg) do
    default = %{
      id: __MODULE__,
      start: {__MODULE__, :start_link, [init_arg]},
      type: :supervisor
    }

    Supervisor.child_spec(default, unquote(Macro.escape(opts)))
  end
end

Keep in mind that’s a pseudo-code as I left the Macro.escape for better understanding of the “expanded” code that happens on the __using__/1 function.

I tried to get this info from the docs, which I could not find that easily so I dig into the code, and as a good surprise this was so easy to find. Check this out.

By the way, the generated code is very similar to the GenServer one for the same function, the only difference is that on the GenServer there’s no :type key, and it works fine because the default value for the :type key is :worker.

Javascript Privates

You can utilize ‘private’ features in a javascript class via the # character prepending a name. They are referred to as ‘hash names’.

These private fields must be declared ahead of time otherwise they will result in a syntax error.

For this example I replaced some declaratively ‘private’ attributes _closed & _balance with actual ‘private’ attributes #closed & #balance.

export class BankAccount {
  #closed
  #balance
  
  set balance(amount) {
    return this.#balance = amount;
  }

  get opened() {
    return !this.closed;
  }

  get closed() {
    return this.#closed == true;
  }
}

It appears that if you’re at Node 12 or higher you can use this functionality.

You can read more about this at MDN

How using fzf in new places rocks

Thanks to joshbranchaud and gabrielreis for these:

Fuzzy git checkout (alias in git config):

[alias]
    fco = !git branch | fzf +m | awk '{print $1}' | xargs git checkout

Then just use git fco and get an interactive fzf session to look through the available branches!

Fuzzy rails routes:

rails routes | fzf

Fuzzy search your routes without needing to run rails routes multiple times!

Using `@describetag` in Elixir Tests

Wow! ExUnit have some special tags for @moduletag and @describetag which are self explanatory if you know what tags are used for in ExUnit. They are so useful in case you want to, for example, only run that section of tests:

defmodule MyApp.AccountsTest do
  use MyApp.DataCase

  @moduletag :module_tag

  describe "search" do
    @describetag :describe_tag

    @tag :test_tag
    test "return all users" do
      user_1 = insert!(User)
      user_2 = insert!(User)

      assert Accounts.search(User) == [user_1, user_2]
    end
    ...
  end
  ...
end

In case you want to run only tests that match with a module (file) level @moduletag:

my_app git:(main) ✗ mix test --only my_module_tag
Excluding tags: [:test]
Including tags: [:my_module_tag]
............
Finished in 0.2 seconds
22 tests, 0 failures, 10 excluded

Or if we want to run all tests that match with a describe block tagged with @describetag:

my_app git:(main) ✗ mix test --only my_describe_tag
Excluding tags: [:test]
Including tags: [:my_describe_tag]
....
Finished in 0.2 seconds
22 tests, 0 failures, 18 excluded

We can see by the number of excluded tests that this works great as expected.

Nullish coalescing operator - ??

Ever need to have a back up default value when something is null or undefined in Javascript? Well a fairly recent addition to JS has got you covered. The Nullish coalescing operator?? may help you on your logical path.

If the first half of the epresssion is ‘nullish’, it will return the latter.

const defaultValue = 'I WIN'
const someVariable = null
someVariable ?? defaultValue
=> 'I WIN'

compare this to using || in which the first half of expression needs to evaluate falsey to get into the latter portion.

As it is a newer part of the JS API make sure to check for browser support. There is also a polyfill available.

How to show constraints in MySQL

Working in Postgres, I’ve gotten used to seeing the contraints on a table listed with \d. Working in MySQL I wasn’t seeing similar with describe <table>;. Turns out you can see all the constraints by selecting from information_schema.referential_constraints:

SELECT * 
  FROM information_schema.referential_constraints 
  WHERE constraint_schema='db_name' 
  AND table_name='table_of_interest';

React SyntheticEvent for Focus and Blur

Some JavaScript events like focus and blur do not bubble to parent elements. Let’s say that we have:

<div
  onfocus="console.log('div focus')"
  onblur="console.log('div blur')"
>
  <input
    type="text"
    placeholder="Type something here"
    onfocus="console.log('input focus')"
    onblur="console.log('input blur')"
  >
</div>

Then if we focus we’ll see in the console input focus and if we blur we’ll see input blur. This makes a lot of sense as a div does not have the concept to focus, there’s no blinking cursor or anything like that.

But in React the scenario is different. In an attempt to standardize all browser events to behave similarly to each other and across different browsers, React wraps all events in SyntheticEvents and for the onFocus and onBlur events we’ll see that they do bubble up:

<div
  onFocus={() => console.log('div focus')}
  onBlur={() => console.log('div blur')}
>
  <input
    type="text"
    placeholder="Type something here"
    onFocus={() => console.log('input focus')}
    onBlur={() => console.log('input blur')}
  />
</div>

Here if we focus we’ll see input focus and div focus in this order and if we blur we’ll see input blur and div blur in this order again.

Use reduced motion to control a video

I used my useWatchMedia hook to play/pause a video based on the reduced motion OS config.

On Macs you can set this option in System Preferences => Accessibility => Display:

image

This way users with motion sickness can have better time browsing your website.

And here’s my video component:

const useReducedMotion = () => {
  return useWatchMedia('(prefers-reduced-motion: reduce)');
};
const MyVideo = ({url}) => {
  const ref = useRef();
  const reducedMotion = useReducedMotion();

  useLayoutEffect(() => {
    if (ref.current) {
      reducedMotion ? ref.current.pause() : ref.current.play();
    }
  }, [ref, reducedMotion]);

  return (
    <video autoPlay loop muted playsInline ref={ref} src={url} />
  );
};

As the browser exposes this config via media query we could also use regular css for that media to enable/disable features, for example css animations.

About cool ways to use file marks

File marks in vim are just marks made with [A-Z]. They have the delightful property that they persist (via .viminfo) across sessions without needing a session (depending on your settings). I’ve known about them for a while, but I wasn’t sure if there was really a way that I could come up with the use them. So I went out looking and found something that I like!

`T -> project todo file
`V -> .vimrc

I’ll probably come up with some other ideas based on the invariant files that I frequently visit, but these two are definitely going into my rotation. I’m also thinking that at least one more should be added:

`L -> TIL file (ABT - always be TILin)

cReddit where credit is due