Today I Learned

A Hashrocket project

Bootstrap CircleCI Setup with Docker 🐳

CircleCI maintains a collection of Docker containers, pre-installed with different languages and tools.

These include language image variants that can eliminate a lot of CI setup churn. I recently used the -browsers variant, which ships with Chrome, Firefox, Java 8, and Geckodriver.

Here’s how you could use such a container.

# .config/circle.yml

version: 2
jobs:
  build:
    docker:
      - image: circleci/ruby:2.5.1-browsers
    steps:
      - run: rake

Named arguments by default

This feature is fantastic and I haven’t seen it in any other language.

You don’t have to declare named arguments, all arguments are named with the argument names by default.

>>> def add(a, b, c):
...     return a + b + c
...
>>> add(1, 2, 3)
6
>>> add(c=1, b=2, a=3)
6

What happens if you mix in named args with positional args

>>> add(1, b=2, c=3)
6

That works, but if you change the order?

>>> add(a=1, b=2, 3)
  File "<stdin>", line 1
SyntaxError: non-keyword arg after keyword arg

That error is definitive which is great. What about using a named arg for an already declared positional argument? Another definitive error:

>>> add(1, a=2, c=3)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: add() got multiple values for keyword argument 'a'

There are so many times in Ruby and in JavaScript(es6 w/destructuring) where I debate whether the arguments should be named or not. I don’t really have a good rhyme or reason to it other than just feel and percieved readability. To not have to think about it seems wonderful.

Show images on git diff

Today I learned how to show binary files, more specifically images, using git diff or git show CLI. For that I am using iTerm2 imgcat.

In order to get there I had to configure git to allow a custom diff command to specific file types.

So I used git attributes to do that:

echo "*.gif diff=image" >> ~/.gitattributes
echo "*.jpg diff=image" >> ~/.gitattributes
echo "*.png diff=image" >> ~/.gitattributes
git config --global core.attributesfile '~/.gitattributes'

Then I had to change the git diff text converter to use iterm2 imgcat:

git config --global diff.image.textconv 'imgcat'

Check this out:

git-diff-images

Notes:

  • imgcat does not work with new versions of tmux
  • git pagers like less or more won’t work either, so you can run git --no-pager diff or you can pipe with cat like:
git diff | cat

Check also Open images in vim

Creating named tuples in Python

Named tuples are an interesting, flexible and fun data structure in Python.

Sorta like an openstruct in Ruby, it’s a quick way to create a finite data structure that has named properties. The properties of a namedtuple are also accessible via index.

from collections import namedtuple
Thing = namedTuple('Thing', ['a', 'b'])
x = Thing(1, 2)
x.a
# 1
x[0]
# 1

You can create an instance of a named tuple with named arguments as well.

x = Thing(b=3, a=4)
# Thing(a=4, b=3)

The properties of a namedtuple can also be declared with a string rather than a list. That looks like this:

Row = namedtuple('Row', 'a b c d')

or comma separated:

Row = namedtuple('Row', 'a, b, c, d')

Imports in ES5

The ES6 import keyword is so pervasive in how we write JavaScript currently that when when I had to “import” the path package in ES5 I didn’t know how to do it!

It’s really easy though, and if you don’t like magic keywords maybe it’s a little more intuitive too.

const path = require('path');

And if something is the default export in it’s module, then you can use the default property.

const Something = require('something').default;

I ran into this in a file that was outside the build path, gatsby-config.js.

Pattern matching against Dates in Elixir

Dates in Elixir aren’t native values, so there aren’t any guard clause functions available for use with date/datetime. You can, however, use pattern matching:

def foo(%Date{} = date) do
  Timex.to_naive_datetime(date) |> foo
end

def foo(%DateTime{} = datetime) do
  Timex.to_naive_datetime(datetime) |> foo
end

def foo(%NaiveDateTime{} = datetime) do
  IO.inspect({"My Naive Datetime", datetime})
end

Delete remote git branch - the declarative way

Cleaning up after yourself is important, and not just in real life. Good Git Hygiene™ goes a long way.

One of the methods I like to clean up is deleting unused feature branches. I do that both locally and on the remote source control server (github/gitlab etc).

As is common with Git there are many ways to feed a cat. Some people use this:

git push origin :name-of-branch

I prefer the more declerative way, especially for potentially destructive operations such as deleting a remote branch:

git push origin --delete name-of-branch

Either way, keeping your remote branches trim makes for a happier development team!

Destructured Access To Nested Value & Parent Value

A destructuring pattern that I often see (especially in React code) is to peel off a nested value in the argument declaration of a function.

const Component = ({ data: { name: displayName }}) => {
  return (
    <div>
      <h1>{displayName}</h1>
      <SubComponent />
    </div>
  );
};

On its own this works quite well, but what happens when you need access to the full set of data as well as the nested name value? I often see this.

const Component = ({ data }) => {
  const { name: displayName } = data;
  return (
    <div>
      <h1>{displayName}</h1>
      <SubComponent data={data} />
    </div>
  );
};

ES6 destructuring is flexible. You can skip the const line and keep everything in the argument declaration.

const Component = ({ data: { name: displayName }, data }) => {
  return (
    <div>
      <h1>{displayName}</h1>
      <SubComponent data={data} />
    </div>
  );
};

You can re-reference the data value after the nested destructuring.

String Interpolation in python??

String interpolation is something that I’ve come to expect from a modern language. Does python have it?

Well, sorta. From this article python has a couple different ways of getting data into a string.

‘Old Style’

'Old Style is a cheap beer from %' % 'Chicago'

‘New Style’

'New Style seems a bit less {}'.format('obtuse')

‘f-Strings’ (from python 3.6)

adejective = 'better'
f'This is a bit {adjective}'

Template Strings

from string import Template
t = Template('This is maybe more like Ruby\'s $tech?')
t.substitute(tech='ERB')

Submit A Form With A Button Outside The Form

You can tie a submit button to a form that the button doesn’t live inside of. The trick is to give the form an id and then reference that id with the button’s form property.

<div>
  <form id="my-form">
    <label for="name">Name:</label>
    <input type="text" name="name"></input>
  </form>

  <!-- ... -->

  <button type="submit" form="my-form">Submit</button>
</div>

With this setup, clicking the Submit button will cause the form to be submitted.

See the MDN Button docs for more details.

Where is that python function defined?

If you want to look at the definition of a function in Python but you don’t know where it’s defined, you can access a special attribute of the function __globals__.

In the following case I have a function imported from nltk called bigram and I want to see what file it’s defined in:

>>> bigram.__globals__['__file__']
'.../python3.7/site-packages/nltk/util.py'

Ah, just as I suspected, it is defined in nltk/util.py

__file__ is an attribute of the globals dictionary.

The special attribute __globals__ is only available for user-defined functions. If you try to access it for a python defined function you’ll get an error:

>>> len.__globals__['__file__']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'builtin_function_or_method' object has no attribute '__globals__'

Python has tuples!

I love a good tuple and in JavaScript or Ruby I sometimes use arrays as tuples.

[thing, 1, "Description"]

In those languages however, this tuple isn’t finite. Wikipedia defines tuple thusly.

a tuple is a finite ordered list (sequence) of elements.

Python tuples look like this:

mytuple = (thing, 1, "Description")

And is it finite?

>>> mytuple.append("c")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'append'

No append attribute, ok. But can you add tuples together?

>>> a = ('a', 'b')
>>> a + ('c', 'd')
('a', 'b', 'c', 'd')
>>> a
('a', 'b')

You can add tuples together but it’s not mutative.

A syntax quirk is the one element tuple.

>>> type(('c'))
<class 'str'>
>>> type(('c',))
<class 'tuple'>

Include a comma after the only tuple element to ensure that the tuple is not tokenized as a string.

Matching A Computed Property In Function Args

The computed property name feature of ES6 allows you to reference a variable in object assignments and destructurings. This syntax is flexible enough that it can be used in the arguments portion of a function declaration. In fact, it can even be matched against another argument — allowing the creation of some handy, yet terse functions.

const get = (key, { [key]: foundValue }) => foundValue;

Notice that the first argument, key, will match against the computed property name in the second argument. The foundValue will correspond to whatever key maps to in the given object.

This get function can then be used like so.

const stuff = { a: 1, b: 2, c: 3 };

console.log("Get a:", get("a", stuff)); // Get a: 1
console.log("Get d:", get("d", stuff)); // Get d: undefined

h/t @sharifsbeat

Delimiters for sed shell command

Today I learned that the sed shell command accepts other delimiters than /. I was trying to run the following:

folder="screens/components"
echo "~/FOLDER/index.js" | sed -e "s/FOLDER/${folder}/g"
# sed: 1: "s/{{folder}}/screens/co ...": bad flag in substitute command: 'c'

But I got a bad flag error. So I changed my delimiter to | and all works fine:

folder="screens/components"
echo "~/FOLDER/index.js" | sed -e "s|FOLDER|${folder}|g"

Quiet noisy ssh port forwarding errors

When you are connecting via ssh to another machine and portfowarding like:

ssh person@machine.name -L 8000:localhost:8000

And there is no server running on port 8000, then you might be getting errors like:

channel 2: open failed: connect failed: Connection refused

If this is the case, you can add the -q flag to your ssh command. The ssh man page documents -q as:

-q      Quiet mode.  Causes most warning and diagnostic messages to be

So the whole ssh command would look like:

ssh person@machine.name -L 8000:localhost:8000 -q

Hopefully this solves your problem!

H/T Brian Dunn

Get the ancestors of a python class

Python has inheritance, but if you encounter a Python object in a program, how can you tell what it’s superclasses are?

mro is an abbreviation for method resolution. Use the mro method on class.

>>> something = object() type(something).mro()
[<class 'object'>] 

This is just an object of type object, it’s only class is object. Let’s get a bit more complicated.

>>> class Fruit:
...     pass ...
>>> class Apple(Fruit):
...     pass ...
>>> Apple.mro()
[<class '__main__.Apple'>, <class '__main__.Fruit'>, <class 'object'>] 

OK, Apple inherits from Fruit which inherits from object. Makes sense!

Chaining `then` in Ruby 2.6

Ruby 2.5 introduced a method yield_self on an object. The idea is simple, just pass self as the argument to a block.

"something".yield_self {|str| str + "!"}
          .yield_self {|str| str + "!"}
# "something!!"

It yields self and returns the result of the block, unlike tap which yields self and returns self.

yield_self feels technical and wordy. Ruby 2.6 introduces an alias for yield_self, then. then feels like something that could mimic the pipe operator (|>) in Elixir. Data transformations can be just a series of thens.

"something"
.then {|str| str.chars.map {|x| x.ord + 1 }}
.then {|ords| ords.map {|x| x.chr }}
.then {|chars| chars.join } 
.then {|str| str + "!" }
.then {|str| str + "!" }
# tpnfuijoh!!

In some cases where a data transformation takes multiple steps, this coding style might make your could cleaner and more intentional.

I look forward to seeing then in your code!

Debugging csound with `printks`

Csound operates uniquely. You can specify certain operations to happen at a certain rate based on the variable name.

kval random 0, 10

This line of code produces a random value between 0 and 10, 1000 times a second because it populates a k-rate (control rate) variable.

But what if I want to debug this? Or see in the console what values I’m producing? You can use the printks opcode.

kval random 0, 10
printks "kval: %f\n", 1, kval

Clearly, 1000 prints a second would eat up the console quickly. printks’s second argument is how many seconds between prints. It’s debouncing printing automatically.

It’s output looks like this:

kval: 9.635761
kval: 6.579237
kval: 6.564805
kval: 7.650385
kval: 3.684652
kval: 2.481188
kval: 3.298008
kval: 5.385859
kval: 0.559652
kval: 5.215418

Read more about it here.

Change the Mac Screenshots Dir

If you like a clean virtual desktop, then placing all screenshots on the Desktop can be incredibly messy.

To change the desktop location:

> defaults write com.apple.screencapture location ~/Desktop/Screenshots

Let’s say you configured this to a weird directoy and you want remember where you are saving screenshots, you can read that configuration.

> defaults read com.apple.screencapture location
~/Desktop/Screenshots

Check The Type Of A Child Component

There is a simple way to check the type of a child component.

import React from 'react';

const Hello = () => <h1>Hello</h1>;

const Greeting = ({ children }) => {
  let hello;
  React.Children.forEach(children, child => {
    if(child.type === Hello) {
      hello = child;
    }
  });

  return hello;
};

This is a comparison of the child’s type to the component constant we are looking for.

This comparison is not the most robust. For instance, Gatsby does something internally that throws off this comparison. Here is a more robust comparison.

if(child.type === Hello || child.type === <Hello />.type)

source

Wrap The Root Of A Gatsby App In A Component

Each component that is defined in the pages directory of a Gatsby app will be generated into a separate static page. Each of these pages is meant to stand on its own. Nevertheless, there is still a behind-the-scenes root component above all of these pages. There are cases where’d you like to wrap this root component with some other component, such as a Redux Provider.

This can be done using the wrapRootElement hook from the Browser API in the gatsby-browser.js file.

// gatsby-browser.js
import React from 'react';
import { Provider } from 'react-redux';

import store from './src/store';

export const wrapRootElement = ({ element }) => {
  return (
    <Provider store={store}>{element}</Provider>
  );
}

Each page and each component in your Gatsby app will now be downstream from a Redux provider meaning that they can connect to the Redux store as needed. You can use this technique for any top-level component that need to be wrapped around the entire app.

source

First Postgres Queries: a Join and an Alias

To see some 2018 TIL stats, I learned to write some Postgres queries. One was:

select developers.username, count(*) from posts join developers on posts.developer_id = developers.id  where published_at >= '2018-01-01' and published_at < '2019-01-01' group by developers.username order by count(*) desc

This gave me the number of posts in 2018 associated with each username. I joined the posts table and the developers table with join developers on posts.developer_id = developers.id. That lines up the developer_id column in the posts table to the id column in the developers table. Now I can select the username column from the developers table: developers.username.

Next, I wanted to see the average number of likes per post for each developer. I do that by having the query evaluate the expression sum(likes)/count(*). I followed that with the phase as average. This creates an alias that can save some thinking and typing later in the query. The final query:

select developers.username, sum(likes)/count(*) as average from posts join developers on posts.developer_id = developers.id  where published_at >= '2018-01-01' and published_at < '2019-01-01' group by developers.username order by average desc

Congrats Taylor, Brian, and Jack for having the most loved posts of 2018!

Ruby 2.6 introduces endless ranges `(1..)`

This syntax is basically a substitute for either (1..Float::INFINITY) or [1, 2, 3][1..-1].

One of the best use cases I’ve seen is from this April 2018 post:

case 2022
when(2030..)
  :mysterious_future
when(2020..)
  :twenties
when(2010..)
  :nowish
else
  :ancient_past
end
#=> :twenties

This reads a lot cleaner than it would with 2010...Float::INFINITY.

Another cool use is a short with_index using zip.

[1, 2, 3].zip(1..) { |a, index| puts "#{a}, #{index}"}
# 1 1
# 2 2
# 3 3

And additionally, you get a bit of safety that you didn’t get with (1..Float::INFINITY):

(1..Float::INFINITY).to_a
# endless loop
(1..).to_a
# RangeError (cannot convert endless range to an array)

Which is a much better outcome for your program!

The shovel `<<` now composes procs in 2.6

The new Ruby 2.6 release definitely has some… uh… gems.

The >> and << operators can now compose procs.

irb> a = ->(){1}
=> #<Proc:0x00007f937a0be158@(irb):33 (lambda)>
irb> b = ->(x){ x + 2}
=> #<Proc:0x00007f937b01fac0@(irb):34 (lambda)>
irb> c = a >> b
=> #<Proc:0x00007f937a148c40 (lambda)>
irb> c.call()
3

Composing procs yes, but really anything that’s callable (implements the call method).

irb> def d; 4; end
:d
irb> e = method(:d) >> b
=> #<Proc:0x00007f937a86b3b0 (lambda)>
irb> e.call()
=> 6

This is cool! I hope I start seeing code taking more advantage of procs, I can see some interesting styles coming from this.

Ruby knows itself

An identity function according to wikipedia is defined as:

a function that always returns the same value that was used as its argument.

This morning I learned that Ruby added an identity function for objects in 2.2, #itself!

> [1, 2, 3].map(&:itself)
[1, 2, 3]

Off the top of my head I can’t think of a good example, but it does come up now and again. The identity function is definitely something to keep in mind!

Change the delimiter in mysql for procedures

Creating procedures in mysql has a weird quirk. When you terminate a statement within the procedure with a ; the entire create procedure statement gets executed up until the semi-colon. This causes a syntax error.

-> create procedure thing()
-> begin
-> set @x = 0;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 3

To get past this, you need to declare a different delimiter so that mysql know when you are ready to execute the entire create procedure statement. To change the delimiter to //, run:

delimiter //

Now you can execute the create procedure statement by putting // after end:

create procedure thing()
begin
  set @x = 0;
end //

Javascript Default Named Parameters

I wanted to create a function with some named parameters as optional values, but I wanted them to have a default value for each option. I could use function({max = 10, min = -10}){} but this only works if you pass a js object as argument. So I added a default object into that and it just works great. Check this out:

avg = function({max = 10, min = -10} = {max: 11, min: -11}) {
  let avg = (max + min) / 2;
  console.log('min', min, 'max', max, 'avg', avg);
  return avg;
}

avg();
// => min -11 max 11 avg 0

avg({});
// => min -10 max 10 avg 0

avg({max: 5});
// => min -10 max 5 avg -2.5

avg({min: 6});
// => min 6 max 10 avg 8

avg({max: 5, min: 6});
// => min 6 max 5 avg 5.5

Default values are different on this example for illustration purposes.

Add an Empty Directory to Git

Have you ever seen a directory containing a single .gitkeep? Today I learned the history of that file.

Git won’t let us add an empty directory, but sometimes there’s a good reason to want to do that. For instance, I’m building a single-page app that requireds a src/data/ directory, even when there’s no data. Instead of each developer on the project making this directory by hand, I’d like to check it into version control.

There are two competing strategies to achieve this: adding a .gitkeep to the directory, or adding a .gitignore. I prefer .gitkeep because the name tells you what it does and it’s not conventionally used for another purpose.

$ touch src/data/.gitkeep

Stack Overflow

Gatsby 404 Static Sitemap

Iterating through a process of building many static Gatsby.js pages at once, I discovered a hacky way to see what pages have been built. Visit a page that doesn’t exist, and Gatsy’s development 404 page will provide a sitemap with links to all the static pages.

demo

It’s a little nicer than digging through the filesystem.

Create A Map Of Strings In ReasonML

ReasonML has the Map.Make functor in its standard library which allows you to create a Map module with a specific key type. Here is how we can make a map module with string keys.

module StringMap = Map.Make(String);

We can then use that module to to create an empty map followed by adding key-value pairs to it.

StringMap.empty
|> StringMap.add("Morty", "Smith")
|> StringMap.add("Rick", "Sanchez")
|> StringMap.add("Scary", "Terry")
|> StringMap.iter((first, last) => {
  print_endline(Printf.sprintf("%s %s", first, last));
});
/*
Morty Smith
Rick Sanchez
Scary Terry
*/

See the live example.

@reach/router Renders To A Div

Check out the following snippet that uses @reach/router.

import { Router } from '@reach/router';

const Home = () => <h1>Home</h1>;

const App = () => {
  return (
    <div className="main">
      <Router>
        <Home path="/home" />
      </Router>
    </div>
  );
}

When you visit ‘/home’, this will render in the DOM as:

<div class="main">
  <div tabindex="-1" role="group" style="outline: none;">
    <h1>Home<h1>
  </div>
</div>

Notice the extra div — that is what <Router> renders to as part of @reach/router’s accessibility features. This may throw off the structure or styling of your app. This can be fixed. Any props that you give to <Router> will be passed down to that div. For instance, you could remove the most outer div and put className="main" on the <Router>.

source

Git Push Force but with lease

If you need to run a git push --force to push a fixup or an amended commit you can try the --force-with-lease tag first for safety. It will protect you to overwrite a commit made by other dev.

alias gplease='git push --force-with-lease'

Check Git push documentation

--force-with-lease will protect all remote refs that are going to be updated by requiring their current value to be the same as the remote-tracking branch we have for them.

Prevent a User From Selecting Text

Today I learned about a CSS property called user-select. You might use it like this, to prevent a user from selecting text:

p {
  user-select: none;
}

I discovered this on an event booking website: the event description links were not anchor tags, and the content on the page was not selectable.

If you’re going to disable default behavior on a website, you need to have a good reason. My assumption (which could be wrong) is that the site creators don’t want me to select text on the page and start searching around for a better deal. I don’t think that’s a good enough reason, because there are plenty of cases where a user might copy text on a page that don’t hurt (or actually support) the event organizer’s business.

docs

Separated Table Borders

Today I learned how to make separated table borders, like this:

border-collapse

Each td has a top and bottom border, and these settings make the separation possible:

table {
  border-collapse: separate;
  border-spacing: 3rem 0rem;
}

The border-collapse property sets whether cells inside a table have shared or separate borders. The border-spacing property sets the distance between the borders of adjacent table cells, when border-collapse is set to separate.

More info: table properties

Accessing Location Within @reach/router

The API of @reach/router departs a bit from react-router in a couple ways. The location prop which you may be used to having access to automatically is instead available through the Location component.

import React from 'react';
import { Location } from '@reach/router';

const MyComponent = () => {
  return (
    <Location>
      {({ location }) => {
        return <p>Current Location: {location.pathname}</p>;
      }}
    </Location>
  );
}

This is a contrived example, but you can imagine how you’d use it to access state or even create an HOC similar to withRouter.

ProxyJump: simplest way to ssh with a jump host

Ever need to jump your ssh through an intermediate host? You may be familiar with using netcat like this in your ~/.ssh/config:

Host jumpy
  ProxyCommand ssh -q jump-host nc destination-host %p

ProxyCommand runs on our local machine. The command must open a tcp connection that ssh may then use for the session. Here we shell into our jump-host, connecting the file descriptors to nc, which will forward all data to destination-host on %p, the port you provided to -p on the cli.

Clear as mud, no?

Another slightly more readable way to achieve this is with -W

Host jumpy
  ProxyCommand ssh -W destination-host jump-host

This works the same way as the nc version, but now we are using ssh’s internal implementation of nc. So one less dependency on the jump host.

But behold, the most legit and legible version of jumping hosts:

Host jumpy
  Hostname destination-host
  ProxyJump jump-host

So same thing, but now the words say what it does.

When you get lost remember that .ssh/config has it’s own man page:

$ man ssh_config

Thanks Dillon!

Creating A 2D Array

In most languages if I wanted to create a two-dimensional array, I would utilize some nested looping construct to generate columns of rows. The ReasonML Array module abstracts this away.

let grid = Array.make_matrix(10, 10, 0);

grid
|> Array.iter(column => {
  column
  |> Array.iter(cell => {
    print_int(cell);
  });
  print_endline("");
});

/*
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
0000000000
*/

The make_matrix function allows you to specify dimensions of a two-dimensional array with all positions initialized to the same value — that third argument.

Pretty Print JSON responses from `curl` - Part 3

If you thought that the output was pretty enough from last TIL, you were wrong.

Dennis Carlsson tweeted me about a tool called bat that has automatically syntax highlighting for a bunch of different languages and can also display line numbers.

Just pipe bat after jq and you are good to go:

> curl 'https://til.hashrocket.com/api/developer_posts.json?username=gabrielreis' | jq  | bat

       │ STDIN
───────┼──────────────────────────────────────────────────────────────────────────────
   1   │ {
   2   │   "data": {
   3   │     "posts": [
   4   │       {
   5   │         "title": "Pretty Print JSON responses from `curl` - Part 2",
   6   │         "slug": "utpch45mba"
   7   │       },
   8   │       {
   9   │         "title": "Pretty Print JSON responses from `curl`",
  10   │         "slug": "pgyjvtuwba"
  11   │       },
  12   │       {
  13   │         "title": "Display line break content in React with just CSS",
  14   │         "slug": "mmzlajavna"
  15   │       }
  16   │     ]
  17   │   }
  18   │ }

If you know any other tricks on making stdout prettier I would love to learn them.

Pretty Print JSON responses from `curl` - Part 2

After posting my last TIL , Vinicius showed me another tool that goes beyond just pretty printing: jq

If you don’t pass any args to jq it will just pretty print same as json_pp:

> curl 'https://til.hashrocket.com/api/developer_posts.json?username=gabrielreis' | jq

{
  "data": {
    "posts": [
      {
        "title": "Pretty Print JSON responses from `curl`",
        "slug": "pgyjvtuwba"
      },
      {
        "title": "Display line break content in React with just CSS",
        "slug": "mmzlajavna"
      },
      {
        "title": "Mutations with the graphql-client Ruby gem",
        "slug": "xej7xtsnit"
      }
    ]
  }
}

What if you only want to display the first post on the response? Just pass an argument to filter the keys you want. It’s like Xpath for JSON: jq '.data.posts[0]'

> curl 'https://til.hashrocket.com/api/developer_posts.json?username=gabrielreis' | jq '.data.posts[0]'

{
  "title": "Pretty Print JSON responses from `curl`",
  "slug": "pgyjvtuwba"
}

See Part 3

Pretty Print JSON responses from `curl`

When you use curl to manually make API calls, sometimes the response is not formatted:

> curl 'https://til.hashrocket.com/api/developer_posts.json?username=gabrielreis'`

{"data":{"posts":[{"title":"Display line break content in React with just CSS","slug":"mmzlajavna"},{"title":"Mutations with the graphql-client Ruby gem","slug":"xej7xtsnit"},{"title":"The rest of keyword arguments 🍕","slug":"o2wiclcyjf"}]}}%

You can pipe json_pp at the end so you have a prettier json response:

> curl 'https://til.hashrocket.com/api/developer_posts.json?username=gabrielreis' | json_pp

{
   "data" : {
      "posts" : [
         {
            "slug" : "mmzlajavna",
            "title" : "Display line break content in React with just CSS"
         },
         {
            "title" : "Mutations with the graphql-client Ruby gem",
            "slug" : "xej7xtsnit"
         },
         {
            "title" : "The rest of keyword arguments 🍕",
            "slug" : "o2wiclcyjf"
         }
      ]
   }
}

See Part 2

Modifying A String With blit_string

ReasonML’s Bytes module has a function called blit_string. This function allows you to copy portions of a string into a destination byte sequence. It is a fairly low-level operation, so you have to provide a source string and provide an offset of that source string to start copying from. You then have to provide a properly sized byte sequence as well as the destination’s starting offset and length of bytes to be copied.

Here is an example of how we can use blit_string to create a copy of the string with the first character removed.

let remove_first_char = (str: string): string => {
  let copy_len = String.length(str) - 1;
  let dst = Bytes.create(copy_len);
  Bytes.blit_string(str, 1, dst, 0, copy_len);
  Bytes.to_string(dst);
};

Notice that once the byte sequence has been copied over, we then need to convert it back into a string.

Generate A Native ReasonML Project With Pesy

Pesy is a CLI utility available from NPM that you can use to generate a ReasonML project that is ready for native compilation. It uses esy for the management of opam packages. It uses Dune for building your library code with the ReasonML and OCaml dependencies.

Assuming you already have pesy installed globally, create a directory for your project and then run:

$ pesy

A project will be generated that is out-of-the-box ready to compile native executables.

Using Optional Labeled Function Args In ReasonML

If you are constructing a function that takes some arguments, but one of those arguments has a reasonable default value, then you can use an optional labeled argument. Labeled arguments are those arguments prefixed with a ~. If you give the argument a default value, then it becomes optional.

let thing = (~a=1, b: int, c: int) => {
  a + b + c;
};

In this case ~a is a labeled argument. It is also optional and will default to 1 if not specified. The other two arguments, b and c, are positional arguments and thus required in order for the function to evaluate.

Here are two ways of using this function either by specifying ~a or excluding it so that it defaults to 1.

thing(~a=2, 1, 1)
|> string_of_int
|> print_endline /* 4 */

thing(1, 1)
|> string_of_int
|> print_endline /* 3 */

See more details here.

Serialize an Elixir pid

I was wondering how to serialize/deserialize a pid for some tricks with Ecto Sandbox and I found out some nice code on phoenix_ecto code. Here it goes my version:

defmodule MyApp.Serializer do
  @spec serialize(term) :: binary
  def serialize(term) do
    term
    |> :erlang.term_to_binary()
    |> Base.url_encode64()
  end

  @spec deserialize(binary) :: term
  def deserialize(str) when is_binary(str) do
    str
    |> Base.url_decode64!()
    |> :erlang.binary_to_term()
  end
end

And the test:

defmodule MyApp.SerializerTest do
  use ExUnit.Case, async: true

  alias MyApp.Serializer

  describe "serialize/1" do
    test "serializes a pid" do
      pid = self()
      assert pid |> Serializer.serialize() |> is_binary()
    end

    test "serializes a map" do
      map = %{foo: :bar}
      assert map |> Serializer.serialize() |> is_binary()
    end
  end

  describe "serialize/1, deserialize/1" do
    test "serializes and deserializes a pid" do
      pid = self()
      assert pid |> Serializer.serialize() |> Serializer.deserialize() == pid
    end

    test "serializes and deserializes a map" do
      map = %{foo: :bar}
      assert map |> Serializer.serialize() |> Serializer.deserialize() == map
    end
  end
end

Using vim-surround With A Visual Selection

The vim-surround plugin allows you to do a variety of actions that have to do with the surrounding characters of text objects.

The S keystroke allows you to surround a visual selection with the following character.

First, make a visual selection. Then hit S. Then hit a surround character such as ( or [ and the area of text that has been visually selected will be wrapped with the respective surround characters.