Today I Learned

Giant Monkeys Learning

19 posts by alexanderpresber @tschadsk

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.

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:

### 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=begin / =end comment style:

=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.

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.

"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.