Will's Ostensible Blog Hobby

Commit every day.

2023-03-06 12:45:00 -0500

Web Application Design: Deletes resource, hard and soft

I talked about the “nomenlature knot” in the last post but after trying to write about it a few times, I came to realize this topic has more rabbit holes than Watership Down. So, I’m deferring my post(s) and maybe starting a new series on it. Since I would rather move forward with the next posts in this series, lets go on with variations on delete actions.

Lots of applications complicate or even replace the action of deleting resources but preserve for the user the notional interface of deletion. There’s many good reasons for this–mainly to smooth recovery from accidents with an “undoable” delete. I usually hear this called a “soft delete”. Lets examine a “soft delete” feature, discuss what makes this different from a “hide” feature, and the setup for a “hard delete” which actually deletes something.

...

2022-12-03 14:30:00 -0500

Web Application Design: CRUD copy actions with side effects

Given a user visiting the view for Wat copy
When the user clicks on the button to submit the Wat copy form
Then the Wat copy is created
And something else happens
And the user redirected to Wat show view for the copied Wat

In this post I want to consider how to design around side effects that might optionally occur in or as part of an action. I’ll just examine the copy feature from the last post since it’s convenient to think about, but this probably won’t be the last time we examine optional side effects. But it should introduce the problem well enough.

...

2022-11-14 12:45:00 -0500

Web Application Design: designing a copy feature on a CRUD interface

Feature: Users may copy a Wat's attributes to a new Wat.

Today we’re going to start looking into adding a “copy” feature to the CRUD interface created using Ruby on Rails scaffolding–see a couple of posts back. We have to start with the high level survey of just two impementations, and, to keep it brief, I’m only going to introduce the complications to be explored and examined later.

...

2022-11-03 18:45:00 -0400

Web Application Design: Ruby on Rails scaffolded interfaces v6 vs v7

I learned a funny thing while building a test application for my next posts, which is that Rails changed their scaffolding templates in 2.7.

I don’t expect it to change my overall plans very much, but here’s a little tangent on the changes.

...

2022-11-01 08:00:00 -0400

Web Application Design: Ruby on Rails scaffolded interfaces

A while back I started writing a post about web application design and it got too big and weird for a single post or even introducing what I wanted to say. So I’m going to start with something short, simple, and obvious: what you get using a Rails scaffold.

...

2022-08-28 11:00:00 -0400

SQL SELECT and ActiveRecord method chaining

I’ve wanted to write about various weirdnesses in SQL’s SELECT statement, how you can only use certain aliases, and derived columns in certain contexts, and how this might be effected by the “execution order” of the query. However, this is a pretty excellent blog post that well introduces the topic:

Which means, all I really need to talk about here, is how I use this to help me write better ActiveRecord expressions.

...

2022-07-23 10:30:00 -0400

Optionality in Ruby: compacting collections follow-up

Write in haste, repent at leisure.

There’s something, I find aesthetically unsatisfying about the example I gave in the last post.

{ :foo => 1,
  :bar => 2,
  :baz => maybe,
  :qux => 4
}.compact.
  merge(wat: 5)

Which is fine, I guess, as illustration of the principle, but I realize that I put mixed the constants and the optional value in the first hash and merged another constant. That’s not what I would actually do and what I would do deserves some words.

...

2022-07-17 10:30:00 -0400

Optionality in Ruby: compacting collections

A handy trick for building parameters with optional arguments is to build a parameter collection allowing the optional values to be nil then run #compact on them. We’ve seen some hints of this, but lets look at the technique more closely.

maybe = [3, nil].sample

[ 1, 2, maybe, 4].
    compact.
    append(5)

  { :foo => 1,
    :bar => 2,
    :baz => maybe,
    :qux => 4
  }.compact.
    merge(wat: 5)

Not much else to be said, really. #compact is defined on Array, Hash, and Enumerable so you’ll likely find it on many other collections. It only works with nil values, but you can generalize the technique with Enumerable#select.

...

2022-06-19 17:30:00 -0400

Optionality in Common Lisp: From Nothing, Everything

A brief follow-up thought I’ve been thinking about, but sort of struggling with too. In Common-lisp, there’s two worlds of values: the world of “atoms” and the world of “lists” and nil is the only member of both. Here’s a kind “Vennish” diagram:

{t [atom (nil] list)}

Why is this simple notion a struggle? I feel like there are a couple of conceptual knots.

...

2022-05-11 19:00:00 -0400

Optionality in Common Lisp: Generalized Booleans

Common Lisp has one “falsy” value: nil. Every non-nil value is considered “truthy”, but there is also a “true” value, t. This union of two-valued “Boolean” logic and a more generic “nothing” vs “something” logic is called the “generialized boolean”.

There’s one little wrinkle to this particular to Common Lisp, which is that nil and the empty list () are considered the same value. Mostly, this is a great convenience when dealing with lists. Let’s explore some other consequences.

...

2022-01-16 15:15:00 -0500

Optionality in Ruby: Using A Canonical List

Let’s say you have a list of optional values–a standard example is data submitted from checkbox inputs–what’s a convenient way of making sure the optional values are “correct”?

I like compare the input with a “canonical list”. Here’s how that works, using Ruby.

...

2021-10-20 08:30:00 -0400

Optionality in Ruby: fetch chain delicacy

It was pointed out to me that this example from the fetch chain post is a little funny-looking:

deep.
  fetch(:foo, {}).
  fetch(:baz, {}).
  fetch(:qux)

and it is, so let’s talk about it!

...

2021-10-17 20:15:00 -0400

Optionality in Ruby: the fetch chain

This one is a simple enough.

Given a deeply nested structure, how could you conveniently fetch a deeply nested value?

Let’s harken back to Ruby < 2.3 and talk about fetch chains!

...

2021-09-05 16:10:00 -0400

Optionality in Python: False Midnight

It was brought to my attention that, for Python2, midnight was also considered “false”.

>>> from datetime import time
>>> t0 = time(0)
>>> t0.isoformat()
'00:00:00'
>>> t0.strftime("%I:%M:%S")
'12:00:00'
>>> bool(t0)
False

Python3 has changed this so that all times are truthy. There’s a good article about it here:

“A False Midnight” https://lwn.net/Articles/590299/

You know what is still False in Python? Zero-length duration instances of the Timedelta class:

>>> import datetime
>>> p0 = datetime.timedelta(0)
>>> bool(p0)
False

https://docs.python.org/3/library/datetime.html#datetime.timedelta

Since they are identity elements of datetime addition, we can add these zero-size timedeltas to our table of identities.

More on that kind of thing later.

...

2021-09-04 10:00:00 -0400

Optionality in Python: Truth Value Testing

Python has, I think, a most admirable notion of “falsification”. We’ll quote the documentation here:

By default, an object is considered true unless its class defines either a __bool__() method that returns False or a __len__() method that returns zero, when called with the object. Here are most of the built-in objects considered false:

  • constants defined to be false: None and False.
  • zero of any numeric type: 0, 0.0, 0j, Decimal(0), Fraction(0, 1)
  • empty sequences and collections: '', (), [], {}, set(), range(0)

Operations and built-in functions that have a Boolean result always return 0 or False for false and 1 or True for true, unless otherwise stated. (Important exception: the Boolean operations or and and always return one of their operands.)

https://docs.python.org/3/library/stdtypes.html#truth-value-testing

You can read about Python’s boolean coercion methods, __bool__ and __len__ here:

Discussion below:

...

2021-07-28 09:30:00 -0400

Optionality in Ruby: using the NullObject pattern

Avdi Grimm has already written a very excellent little article about using a Null Object pattern for optionality support in Ruby. You should all read it:

https://avdi.codes/null-objects-and-falsiness/

Grimm talks about the limits of this pattern in Ruby and those limits all orbit around the non-extensibility of Ruby’s native NilClass. I don’t have mucht to say, but what follows are a couple of implications I think worth expanding on.

...

2021-07-18 10:15:00 -0400

Optionality in Ruby on Rails: modifying params--why not don't

I talked with a couple of folks about my last post, and based on those conversations and further experiments, I’m going to suggest a different approach, one that doesn’t require mutating the params values.

For one thing, you really should make a solid effort at avoiding it. The params is already exposed to lots of things, and while they shouldn’t be meddling with it, neither really, should we. Also, we don’t have to, since ActionController::Parameters has a pretty solid interface, such that it can be avoided in most circumstances.

...

2021-07-14 20:00:00 -0400

Optionality in Ruby on Rails: modifying params

I’m under the impression that manipulating the incoming params to Rails controller methods is considered something of a code smell if not an antipattern. Rationales for avoiding this include:

  • Is it really the controller’s job?
  • What about strong parameters?
  • General Hazards of mutability

I can’t do anything about the first one. However, I can readily believe that it may become necessary for Reasons. If you have to, you have to. Below the fold I’ll show a short pattern to deal with the next two.

...

2021-06-29 04:10:00 -0400

Optionality and Shell Variable Expansion

Recently I’ve had to recreate my command-line environment at work, and, naturally enough, this has lead to some reforms in my home configuration as well. One of the things I made use of was the parameter expansion features which I want to talk about.

If you aren’t familiar with the parameter expansion feature you should definitely check out this section of the Bash manual:

https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html

There’s more info and usage suggestions from “Advanced Bash-Scripting Guide” here:

https://tldp.org/LDP/abs/html/parameter-substitution.html

...

2021-02-15 23:00:00 -0500

Fundamental Arithmetic

I was planning on sharing this with a math teacher friend to see what he thought. Maybe he would find something pedagogically useful in it. Maybe he would help me understand it better myself–he loved teaching and often wrote about what delight he found in helping a student “get it”. Unfortunately he passed away a couple of days ago. So, in memoriam, here are some idle thoughts on basic arithmetic. I wasn’t sure how to wind it up, so it ends sort of suddenly. He would have found that funny.

...

2018-10-03 23:30:00 -0400

Refactoring the Castle

for each desired change, make the change easy (warning: this may be hard), then make the easy change

—Kent Beck https://twitter.com/kentbeck/status/250733358307500032?lang=en

I’ve been working on Wizard’s Castle lately, fixing some bugs and making some incremental improvements.

Quick background: I “translated” this a few years ago, from the original Basic to teach myself some things about Common Lisp and about control and data-flow for simple games, about going from GOTOs to structures and function calls1.

But I keep tinkering with it because … I made some mistakes. I didn’t understand how to use some of the language features, reinvented some wheels, and generally “over-engineered”. The temptation to re-write is strong, as it’s a small program and I’ve learned a lot of things since.

But it works.

I should say, I have, in fact rewritten a lot of it, in another file, but that’s not a working game. It’s better code in most respects, except the most crucial one. The challenge I see for myself now, is, how do I go about making it better while conserving it’s status as a working game?

So I’ve resumed fiddling with it to exercise how to plan progressive improvements, execute refactoring strategies, and the discipline of not breaking the game.

… but let’s get real. Although I like to imagine this as a self-improvement effort for developing relevant professional skills, I have to admit, the way I gravitate to this project is almost certainly therapeutically motivated.

Consider: A small, low-stakes project, of obscure provenance, with a personal, nostalgic connection—it’s not the kind of thing that one works on when looking forward in life, at least not if they like what they see ahead.

You’ve read the news. We’d all rather wander magic castles full of monsters than do the real world work of making incremental improvements in the systems we use to distribute justice and mercy in society. Now doesn’t seem like the time to be working on little games.

Still, it’s the one area of my life right now where doing a little thing, for the sake of a little thing, will seem like Enough.


1 Also because, hilariously, CL is roughly contemporaneous, although perhaps I should have used Scheme.

...

2017-06-03 08:30:00 -0400

Retro retrospective

One nice thing about writing about one’s mistakes, is that one never runs out of material to write about.

...

2017-03-21 13:00:00 -0400

Candy part 4

“Pez”: A triumph of packaging and presentation over it’s unpalatable and pellet-like product. Short sell the collectors’ market for fun and profit.

...

2017-03-20 13:00:00 -0400

Candy part 3

“Skittles”: Defects from a plastic bead factory repurposed to destroy dental fillings and promote cavities by the dental-confectionary complex. Write your legislators to have them banned.

...

2017-03-18 13:20:00 -0400

Candy part 1

It’s been almost a year since my last post, so I recently asked some friends,

Choosing a series topic for reviving my blog: refresh and resume the last topic which was Elixir strings and Unicode or brand new topic: macros in various languages?

I got one suggestion, “Do candy reviews.”

So here goes, for you, my dear friend, Ramiro.

“Reese’s Peanut Butter Cups”: put straight in the trash.

...

2016-05-10 16:00:00 -0400

Unicode and Elixir part 5: Where Elixir Unicode modules are used

Review: here’s a list of modules defined in elixir/lib/elixir/unicode/unicode.ex:

  • String.Unicode
  • String.Casing
  • String.Break
  • String.Normalizer

What we’ll find when we go searching for uses of these modules in the rest of Elixir is they’re cheifly used in elixir/lib/elixir/lib/string.ex.

...

2016-05-04 22:00:00 -0400

Unicode and Elixir part 4: Unicode data files

Unicode is a big catalog of numbers and relationships between that ideally describes human written communication in as many languages as possible. Elixir implements a segment of it in it’s String type. For that it relies on a few data files drawn from or derived by the Unicode Character Base.

...

2016-04-30 12:30:00 -0400

Unicode and Elixir part 3: Elixir's Unicode source

Today we’re going to survey the core Unicode source in Elixir. Again, I’m keeping it very light. I realize we’re very much in the “shallow end of the pool”, as it were, and I think that’s okay. The topic is big and complex, the code and language are still new to me. I’m aiming for posts of about 500 to 1000 words and by controlling the size of these posts, I hope to limit their complexity when we get to the highly technical stuff. For now, we take the time to get to know the major features and landmarks.

...

2016-04-28 12:30:00 -0400

Unicode and Elixir part 2: Where Elixir defines and uses Unicode

Again, in the interest of keeping this light, I’m just going to survey where String and Unicode-related functionality is defined in Elixir source.

...

2016-04-25 18:15:00 -0400

Unicode and Elixir, part 1: Introduction

For the next few posts, at least, I’m going to write about Unicode, how it’s implemented and used in Elixir. I intend to keep these posts shorter than the last series so I can keep it much more lightweight and regular. However, I’m a pretty ambitious guy, and I like getting carried away with things, also, the scope of this extends in two directions with a lot of ground, at the same time, personally, there’s a lot of “life happens” stuff happening, so … we’ll see.

At first though, lets get oriented. Here’s a few resources we’re going to get familiar with as we go along.

From the Elixir Getting started book Chapter 6: Binaries, strings and char lists. Here you can read about how strings in Elixir work. There’s two kinds, but I expect to focus on strings as binaries, rather than as char lists.

From Elixir’s docs, the String module documentation will be our reference for the different operations on Elixir’s strings. Other module documentation of note: Enum and possibly StringIO.

From Elixir’s source, we’ll find most of what we’re interested in lib/elixir/unicode folder.

From http://unicode.org we’ll want to get up to speed on the unicode specification. Elixir is currently on Unicode 8.0.0, but Unicode 9.0.0 is coming out June 2016, with a bunch of new characters and important other changes.

And that last bit gets to heart of why I’m writing this. How does the a project like Elixir implement and keep up with a large and complicated standard like Unicode? Unicode as a standard of character representation and Elixir as a language for humans and computers to share, occupy an intersection where the crosswinds of mathematical numbers and strings with thousands of years of human traditions around reading and writing stir and mix. If find this negotiated territory between computation and communication with all of the conflicts and compromises very interesting. If you do too, please follow along!

...

2016-04-09 15:30:00 -0400

POODCL part 11: Designing effective tests

This has been a long time in coming and this post is long in the reading. Chapter 9, the last chapter of POODR, is called “Designing Cost-Effective Tests” and might be my favorite chapter.

We start with a summary of the three basic skills required for writing well designed, easily changeable code.

  1. Design code with the principle of changeability. “Poorly designed code is naturally difficult to change. From a practical point of view, changeability is the only design metric that matters; code that’s easy to change is well designed.”
  2. Refactor existing code to improve it’s design. “Good design preserves maximum flexibility at minimum cost by putting off decisions at every opportunity, deferring commitments until more specific requirements arrive. When that day comes, refactoring is how you morph current code structure into one that accomodates the new requirements.”
  3. Write high value tests. “Tests give you confidence to refactor constantly. Efficient tests prove that altered code behaves correctly without raising overall costs. Good tests weather code refactorings with aplomb; they are written such that changes to the code do not force rewrites of the tests.” (pg, 192)

In the earlier chapters we’ve been rehearsing the first two. In the last we begin work on the third. Let’s see how to write high value tests in Common Lisp.

...

2015-01-07 04:38:38 -0500

POODCL part 10: Composition, part 3

During my investigation of the composite pattern, the following message came through loud and clear:

Prefer composition to inheritance.

And one of the things I came to wonder about was, if composition is to be preferred, why isn’t there better support for it in object oriented languages? I had a few thoughts about this. Most of them sort of wrong, but here’s what I learned.

...

2014-12-07 22:52:45 -0500

POODCL part 9: Composition, part 2

At the end of chapter 8 of POODR I felt very puzzled and didn’t have confidence in my understanding of the Composite pattern as presented, even after doing a translation of it in Common Lisp as above. This was unusual situation in my experience of reading this this book, and I thought I really should dig into the subject of the Composite pattern to see what it was I was missing.

I think what it is, is that the Composite pattern is more complex, powerful, and involving than presented in the example. Metz’s text on the subject indicates this, but without an example that really demonstrates this, I found it hard to see through to appreciate the Composite pattern until I read more on the subject in other books.

I should say, POODR has still been an enormous help to me, and I recommend it with the only caveat so far, that a beginner may need some additional support in understanding the Composite pattern in this chapter.

It’s a small, thing, but I’m going to dwell on it. I’m going to try a rather naive implementation of the Composite pattern in Common Lisp but try to make it so it demonstrates it’s power and utility, in a way I will probably be unsatisfied with, ultimately, but at least I tried.

...

2014-09-21 07:54:31 -0400

POODCL part 8: Composition, part 1

So it’s been an epic year for me and I haven’t had a lot of time to work on this, except here and there. I also ran into a bit of a conceptual blocker that took a while to resolve, but more on that later.

Object oriented techniques allow us to start thinking about composing complex objects out of simpler ones. Class slot values can be objects of our other classes, not just the basic types provided by the language.

We’re going to take another look at the BICYCLE class and see different ways of composing it from simpler PART objects.

...

2013-11-10 09:55:45 -0500

POODCL part 7: Roles, mixins, and templates

Chapter 7 of POODR opens with the question of what would happen if we need to develop recumbent mountain bikes? This is where we begin to engage with inheritance more seriously. Metz proceeds to introduce Ruby modules and how to identify roles for your code, but before we discuss that aspect of we should look at the simplest answer in Common Lisp.

(defclass recumbent-mountain (recumbent-bike mountain-bike) ())

That’s it.

CL-USER> (tire-size (make-instance 'recumbent-mountain :rear-shock "Fox" 
                                   :flag "tall and red"))
"28"

We should note that the order of the superclasses matters for CLOS objects. Here’s MOUNTAIN-RECUMENT:

(defclass mountain-recumbent (mountain-bike recumbent-bike) ())
CL-USER> (tire-size (make-instance 'mountain-recumbent :flag "tall and yellow" 
                                   :rear-shock "Fox"))
"2.1"

Order of the superclasses is defines the “class precedence list” which CLOS’s uses for method combination.

Let’s move on to the other examples and concepts in this chapter.

...

2013-09-11 07:21:30 -0400

POODCL part 6: Inheritance

Chapter 6 of POODR discusses inheritance of class properties. You can define subclasses whose objects have all the properties of their superclasses plus whatever other properties we define for them. Subclasses are specialized, more concrete versions of their more general, more abstract superclasses.

In the code for POODR chapter 6, Metz approaches strategies for designing inheritable classes starting with a concrete Bicycle class. It begins as a class of road bikes and progressively gets abstracted to provide an abstract class for road, mountain, and recumbent bikes. I’ve translated the examples into Common Lisp and discussed how to refactor them.

...

2013-09-08 14:42:24 -0400

POODCL part 5: Duckish typing

The purpose of object oriented design is to reduce the cost of change.

One of the ideas behind type systems is that a language compiler can make some optimizations if it knows about the type of objects it will be dealing with in runtime. Common Lisp allows, but does not require, a programmer to declare types ahead of time. Ruby doesn’t care about types at all, if an object has a method, it can be called. This is called “Duck typing” after the idea that, “if it walks like a duck, swims like a duck, and quacks like a duck” then we can call it a duck.

However, just because Ruby pretty much ignores types, programmers might feel tempted, even subconsciously, to write type-sensitive code. Chapter 5 of POODR gives us a couple of examples in Ruby, and discusses how to rewrite these. I’ll review and translate these examples in Common Lisp.

...

2013-08-28 23:16:01 -0400

POODCL part 4: Rubyish attr_accessors for CLOS

I mentioned that we could write a Lisp macro to allow us to define class instance-variables like Ruby does. I think it’s worth seeing this, not only to see some of the usefulness of Lisp macros but to see some of the considerations you have to make when using them to extend Lisp.

...

2013-07-31 01:58:28 -0400

Practical Object Oriented Design in Common Lisp part 3

Hiding data structures in the next strategy Metz discusses in Chapter 2. Just as hiding instance variables with accessors, is a good idea, we’ll see how hiding data structures also makes your code more flexible. Again we’ll adapt the sample code to Common Lisp and see how these principles work in CLOS.

...

2013-07-28 03:48:31 -0400

Practical Object Oriented Design in Common Lisp part 2

In POODR chapter 2 in the section called “Writing Code That Embraces Change” Metz discusses two strategies: hiding instance variables and hiding data structures. I’m going discuss the first of these.

Metz strongly recommends wrapping instance variables in accessor methods instead of directly referring to them.

...

2013-07-27 10:36:49 -0400

Practical Object Oriented Design in Common Lisp part 1

I learned a lot when I first read Sandi Metz’s Practical Object Oriented Design in Ruby (POODR), but one of the things I have wondered was how much I would be apply in Common Lisp’s Object System (CLOS). At the time, I didn’t know CLOS very well, but I knew it was very different from Ruby’s object system. CLOS has multiple-inheritance and multiple-dispatch. The notion of “message passing” as guiding metaphor for OOP doesn’t even work for CLOS. How would lispers apply Sandi Metz’s advice?

...

2013-06-08 21:25:40 -0400

Vacation over

This is the first weekend after my first week at my new job. I had a nice break between Portland Code School and my new gig at CrowdCompass. But now that old feeling of the weekend rush is back and I’m right back into it. I feel like there must be some kind of time-management trick I never quite learned for making the most of evenings and weekends while getting the necessary amount of rest.

...

2013-05-05 13:42:54 -0400

Post RailsConf

Whew!

My last week at Portland Code School was over a week ago, but last week we volunteered at Railsconf 2013 which was a tremendous opportunity to meet and hear from luminaries from throughout the Ruby and Rails Community. I got to meet and shake hands with Sandi Metz, ask Richard Schneeman questions about object inspection and using the standard library. As a volunteer I helped everyone with a last name starting with P,Q or R get registered (I feel sure that we at Team M-R had the fastest moving line). I helped Aaron Patterson find the Speaker’s Lounge, and sold leftover Railsconf 2013 T-shirts to raise money for Kids Ruby including to people going to another conference going on nearby.

...

2013-03-16 16:37:38 -0400

Pairing up

Last week it seemed to me that something had been going awry in our pair challenges. I felt that our lack of pairing had left us somewhat unpracticed in team development. I thought maybe we had been concentrating on getting our hands-on coding. I mentioned it to Chuck and he assured me that this was probably okay, at least for the beginning of the course. But he challenged me to spend this week pairing with others and letting them lead.

...

2013-03-09 20:19:30 -0500

Good and Evil

Faust: Well now, who are you, then?

Mephisto: One of the party that ever wishes evil, yet ever yeilds good.

Goethe, Faust

This week at Portland Code School we found ourselves enmired in the primal struggle of Good against Evil.

It began on Monday, during our pitch session for our team projects, Neilson proposed a Cards Against Humanity app where people could vote on plays they thought funniest. Just like the game, but on the web. Our interest was to see what combinations would prove to be the most popular and we may yet find this out, but not before learning of some unsettling possibilities.

...

2013-02-28 17:33:00 -0500

Updates to StarMaze and Wizard's Castle

How embarrassing to show off one’s code and find bugs right away, but there it was.

In StarMaze, the show-near function didn’t work. This turned out to be do to an experimental feature in the map legend and could be fixed by commenting out the experimental stuff. I’ll put it back when the experimental feature are working.

...