Today I Learned

Giant Monkeys Learning

19 posts by alexanderpresber

Global prompt for Claude Code (CLI)

For Claude Code CLI there are two mechanisms for cross-project preferences:

1. ~/.claude/CLAUDE.md – For instructions and context (equivalent to the claude.ai preferences in https://claude.ai/settings/general)

# My Coding Standards

- Test Driven Development: Specs first
- Focus on relevant specs (request, feature, complex methods)
- No trivial boilerplate specs
- Indentation: 2 spaces
- Lean, human-readable code
- When unclear: ask one clarifying question
...

2. ~/.claude/settings.json – For technical settings (permissions, tools, hooks)

{
  "permissions": {
    "allowedTools": ["Read", "Write", "Bash(bundle exec rspec *)"]
  }
}

The CLAUDE.md is loaded at every session start and is the right place for your coding preferences. The settings.json is more for tool permissions and hooks.

NOTE: The settings in https://claude.ai/settings/general are only for the web chat and do not take effect in Claude Code nor in API calls.

Find out your IP from the console

curl ifconfig.me

That's it!

Fake HTTP responses and response times

If you need an HTTP endpoint replying with a specific HTTP status code or taking a specific response time: try https://httpstat.us!

For example: * return a 200 OK success status, taking 5 seconds: https://httpstat.us/200?sleep=5000 * return a 400 Bad Request: https://httpstat.us/400

git commits from then to now

To show all commit children from a specific commit to current master, use git log like bash git log --reverse --ancestry-path 894e8b4e93d8f3^..master

Method git history with `git log -L`

Today I found out that - via git log -L - it's possible to list the history of changes to a specific method:

$ git log -L :initialize:app/lib/giant_money.rb -n5

commit e6ef7f8a3cf06af2ecbf8a528ad5cf312a8d03b1
Author: Alexander Presber <post@momolog.info>
Date:   Sun Aug 13 20:05:59 2023 +0200

    don't fail hard (yet) on GiantMoney[nil] [GOM-8932]

diff --git a/app/lib/giant_money.rb b/app/lib/giant_money.rb
--- a/app/lib/giant_money.rb
+++ b/app/lib/giant_money.rb
@@ -16,12 +16,16 @@
   def initialize value, allow_nil: false
-    raise "GiantMoney.new: value cannot be nil." unless value || allow_nil
+
+    unless value || allow_nil
+      # raise "GiantMoney.new: value cannot be nil." # don't fail hard (yet) on GiantMoney[nil]
+      Rollbar.error("GiantMoney.new: value cannot be nil in #{caller[2]}.", stack: caller)
+    end

     @amount = case value
       when nil      then nil
       when Money    then value
       when Integer  then Money.new(value)
       when Float    then Money.new((value * 100.0))
       else raise 'GiantMoney.new: value needs to be an Integer, Float or Money object.'
     end
   end


commit f55678a8c33029b1e998e1e0b6d536afd2f77107
Author: Lion Vollnhals <lion@giantmonkey.de>
Date:   Fri Jun 9 12:58:05 2023 +0000

    giant_monkey: multiple float by float

diff --git a/app/lib/giant_money.rb b/app/lib/giant_money.rb
--- a/app/lib/giant_money.rb
+++ b/app/lib/giant_money.rb
@@ -16,12 +16,12 @@
   def initialize value, allow_nil: false
...

Noice.

Copy-paste friendly executable comments in Ruby

Imagine this comment on top of a ruby file: ```ruby

usage:

reset and seed database

rake db:reset

get korona base data

rails runner 'Korona.synchronize_all!'

create valid day tickets in local development

rails runner rails-runner/create_valid_ticket_for_shop_tests.rb

It is supposed to document the usage and gives executable example lines. However to use them verbatim you have to copy-paste them line by line, removing the leading `#`.

There is a better alternative using the [mostly frowned upon](https://stackoverflow.com/a/3000121/1162143) `=begin` / `=end` comment style:
```ruby
=begin usage:
rake db:reset                                                   # reset and seed database
rails runner 'Korona.synchronize_all!'                          # get korona base data
rails runner rails-runner/create_valid_ticket_for_shop_tests.rb # create valid day tickets in local development
=end

Now it is possible to copy-paste the whole block into a shell to execute.

Ours and theirs in git rebase

When resolving a conflict while doing a git rebase, --ours does not refer to the branch we are currently on (the one being rebased) but the base branch, e.g. main.

While arguably being pretty confusing, this actually has a good reason.

A nice cheat sheet is here.

Hyphens and underscores in mysql.cnf

According to this bug _and - may both be used in mysql / mariadb configuration options inside the mysql.cnf file.

E.g. [mariadb] log-bin # enable binary logging and [mariadb] log_bin # enable binary logging are both ok!

For googling and searching inside pages the _ variant usually works better.

Capybara content matchers cheat sheet

There's a cheat sheet I use to determine the capybara content matcher to use for a specific purpose:

Wait for some text to eventually be there:
expect(page).to have_content('some text')

Succeeds as soon as the text is there and can be very fast.

Wait for some text to be - and stay - there:
expect(page).not_to have_no_content('some text')

Succeeds if the text stays there for the whole default_max_wait_time and is therefore always slow. But sometimes needed.

Wait for some text to eventually disappear:
expect(page).to have_no_content('some text')

Succeeds as soon as this text is not there and can be very fast.

Wait for some text to be - and stay - absent:
expect(page).not_to have_content('some text')

Succeeds if the text stays absent for the whole default_max_wait_time and is therefore always slow. But sometimes needed.

Sandboxed rails console

If you want to do some changes to your models in the console but want them to be rolled back after your session, just use rails console --sandbox Straight from the docs.

It's not a good idea to use this in production, though.

Ripgrep: searching with negative lookahead

Using ripgrep we can search using PCREs. First we need to enable pcre expressions in ~/.ripgreprc: --pcre2 Then we can search for all occurences of myword not followed by _: ```

rg 'myword(?!_)' ```

Ansible: decrypt single vault value in the shell

$ ansible localhost -m debug -a 'var=my_password'
localhost | SUCCESS => {
    "my_password": "not secret anymore"
}

Delete duplicates with PostgreSQL using USING

Consise way to delete duplicates (depending on a condition, e.g. col1 and col2 being equal) while keeping the row with the highest id:

DELETE FROM
          my_table delete
    USING my_table check
  WHERE
        delete.id < check.id
    AND delete.col1 = check.col1
    AND delete.col2 = check.col2

Using ngrok with puma-dev

If you have a local Rails/Rack server running using puma-dev, e.g. http://gomus.test and you want to use ngrok for accessing this server from remote, you can pass a --host-header=gomus.test to ngrok.

ngrok http --host-header=gomus.test localhost:80

Happy hacking!

Javascript Array.prototype.sort() ...

... by default converts the array elements into strings and sorts them by their UTF-8 Codepoints 🤪!

[-7, 2, 10, -1].sort()
[-1, -7, 10, 2]

You can pass a function to sort to override the behavior: [-7, 2, 10, -1].sort(function(a,b){ return a - b }) [-7, -1, 2, 10]

Phew.

"Fixing" frontend form validations

Some form inputs apply pattern checks (e.g. on the telephone number).

An example: <input type="tel" name="field_mobil" class="phone form-control col-md-3" id="input-handy" value="" required="" size="20" pattern="[0-9]+">. This specific one made the form not accept my telephone number even though it was correct. Removing the pattern attribute using the WebInspector made the validation go away.

This is just to be expected, but still something that feels weird.

DGN provides free S/MIME certificates

The Deutsches Gesundheitsnetz offers free S/MIME certicate creation. These certificates work with Apple Mail (and presumably with Google Mail, but the steps for installing are not completely clear to me) and are valid for one year.

Get the database URL of a Gigalixir app via CLI

Install jq if you haven't already.

Then

gigalixir pg | jq ".[0].url"

Gigalixir is a Heroku alternative for Elixir

Heroku works as a platform for deploying Elixir apps, but has some serious limitations.

Gigalixir is an interesting alternative that was tailored to provide the full Elixir experience in a very Heroku-like fashion including * a powerful CLI * configuration via env vars and * deployments via git push.

You can see it working right here!