mirror of
https://github.com/jbranchaud/til
synced 2026-01-20 15:38:02 +00:00
Compare commits
1 Commits
b1a41f72b6
...
db0530eb90
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
db0530eb90 |
@@ -10,7 +10,7 @@ pairing with smart people at Hashrocket.
|
|||||||
|
|
||||||
For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186).
|
For a steady stream of TILs, [sign up for my newsletter](https://crafty-builder-6996.ck.page/e169c61186).
|
||||||
|
|
||||||
_1534 TILs and counting..._
|
_1531 TILs and counting..._
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -398,7 +398,6 @@ _1534 TILs and counting..._
|
|||||||
### Go
|
### Go
|
||||||
|
|
||||||
- [Access Go Docs Offline](go/access-go-docs-offline.md)
|
- [Access Go Docs Offline](go/access-go-docs-offline.md)
|
||||||
- [Add A Method To A Struct](go/add-a-method-to-a-struct.md)
|
|
||||||
- [Build For A Specific OS And Architecture](go/build-for-a-specific-os-and-architecture.md)
|
- [Build For A Specific OS And Architecture](go/build-for-a-specific-os-and-architecture.md)
|
||||||
- [Combine Two Slices](go/combine-two-slices.md)
|
- [Combine Two Slices](go/combine-two-slices.md)
|
||||||
- [Do Something N Times](go/do-something-n-times.md)
|
- [Do Something N Times](go/do-something-n-times.md)
|
||||||
@@ -408,7 +407,6 @@ _1534 TILs and counting..._
|
|||||||
- [Parse Flags From CLI Arguments](go/parse-flags-from-cli-arguments.md)
|
- [Parse Flags From CLI Arguments](go/parse-flags-from-cli-arguments.md)
|
||||||
- [Replace The Current Process With An External Command](go/replace-the-current-process-with-an-external-command.md)
|
- [Replace The Current Process With An External Command](go/replace-the-current-process-with-an-external-command.md)
|
||||||
- [Sleep For A Duration](go/sleep-for-a-duration.md)
|
- [Sleep For A Duration](go/sleep-for-a-duration.md)
|
||||||
- [Sort Slice In Ascending Or Descending Order](go/sort-slice-in-ascending-or-descending-order.md)
|
|
||||||
- [Upgrading From An Older Version On Mac](go/upgrading-from-an-older-version-on-mac.md)
|
- [Upgrading From An Older Version On Mac](go/upgrading-from-an-older-version-on-mac.md)
|
||||||
|
|
||||||
### GROQ
|
### GROQ
|
||||||
@@ -1224,7 +1222,6 @@ _1534 TILs and counting..._
|
|||||||
- [Define Multiline Strings With Heredocs](ruby/define-multiline-strings-with-heredocs.md)
|
- [Define Multiline Strings With Heredocs](ruby/define-multiline-strings-with-heredocs.md)
|
||||||
- [Destructure The First Item From An Array](ruby/destructure-the-first-item-from-an-array.md)
|
- [Destructure The First Item From An Array](ruby/destructure-the-first-item-from-an-array.md)
|
||||||
- [Destructuring Arrays In Blocks](ruby/destructuring-arrays-in-blocks.md)
|
- [Destructuring Arrays In Blocks](ruby/destructuring-arrays-in-blocks.md)
|
||||||
- [Disable Interpolation For A Heredoc String](ruby/disable-interpolation-for-a-heredoc-string.md)
|
|
||||||
- [Disassemble Some Codes](ruby/disassemble-some-codes.md)
|
- [Disassemble Some Codes](ruby/disassemble-some-codes.md)
|
||||||
- [Double Splat To Merge Hashes](ruby/double-splat-to-merge-hashes.md)
|
- [Double Splat To Merge Hashes](ruby/double-splat-to-merge-hashes.md)
|
||||||
- [Edit Previous Parts Of The Pry Buffer History](ruby/edit-previous-parts-of-the-pry-buffer-history.md)
|
- [Edit Previous Parts Of The Pry Buffer History](ruby/edit-previous-parts-of-the-pry-buffer-history.md)
|
||||||
|
|||||||
@@ -1,70 +0,0 @@
|
|||||||
# Add A Method To A Struct
|
|
||||||
|
|
||||||
Given a `struct` in Go, we can attach a method to that struct. Put another way,
|
|
||||||
we can define a method whose receiver is that struct. Then with an instance of
|
|
||||||
that struct, we can call the method.
|
|
||||||
|
|
||||||
Let's say we are modeling a turtle that can move around a 2D grid. A turtle has
|
|
||||||
a heading (the direction it is headed) and a location (its current X,Y
|
|
||||||
coordinate).
|
|
||||||
|
|
||||||
```go
|
|
||||||
type Heading string
|
|
||||||
|
|
||||||
const (
|
|
||||||
UP Heading = "UP"
|
|
||||||
RIGHT Heading = "RIGHT"
|
|
||||||
DOWN Heading = "DOWN"
|
|
||||||
LEFT Heading = "LEFT"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Turtle struct {
|
|
||||||
Direction Heading
|
|
||||||
X int
|
|
||||||
Y int
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
We can then add a method like so by specifying the receiver as the first part
|
|
||||||
of the declaration:
|
|
||||||
|
|
||||||
```go
|
|
||||||
func (turtle *Turtle) TurnRight() {
|
|
||||||
switch turtle.Direction {
|
|
||||||
case UP:
|
|
||||||
turtle.Direction = RIGHT
|
|
||||||
case RIGHT:
|
|
||||||
turtle.Direction = DOWN
|
|
||||||
case DOWN:
|
|
||||||
turtle.Direction = LEFT
|
|
||||||
case LEFT:
|
|
||||||
turtle.Direction = UP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
The receiver is a pointer to a `Turtle`. The method is called `TurnRight`.
|
|
||||||
There are no parameters or return values.
|
|
||||||
|
|
||||||
Here are a sequence of calls to demonstrate how it works:
|
|
||||||
|
|
||||||
```go
|
|
||||||
func main() {
|
|
||||||
turtle := Turtle{UP, 5, 5}
|
|
||||||
|
|
||||||
fmt.Println("Turtle Direction:", turtle.Direction)
|
|
||||||
//=> Turtle Direction: UP
|
|
||||||
|
|
||||||
turtle.TurnRight()
|
|
||||||
|
|
||||||
fmt.Println("Turtle Direction:", turtle.Direction)
|
|
||||||
//=> Turtle Direction: RIGHT
|
|
||||||
|
|
||||||
turtle.TurnRight()
|
|
||||||
|
|
||||||
fmt.Println("Turtle Direction:", turtle.Direction)
|
|
||||||
//=> Turtle Direction: DOWN
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
[source](https://go.dev/tour/methods/1)
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
# Sort Slice In Ascending Or Descending Order
|
|
||||||
|
|
||||||
The [`slices.Sort`](https://pkg.go.dev/slices#Sort) function defaults to
|
|
||||||
sorting a slice in ascending order. If we want to control the sort order, we
|
|
||||||
have to do a little more work. We can reach for the
|
|
||||||
[`slices.SortFunc`](https://pkg.go.dev/slices#SortFunc) function. This allows
|
|
||||||
us to define a sort function and in that function we can control whether the
|
|
||||||
sort order is ascending or descending.
|
|
||||||
|
|
||||||
Here I've defined `SortItems` which takes a list of items constrained by the
|
|
||||||
[`cmp.Ordered`](https://pkg.go.dev/cmp#Ordered) interface (so things like
|
|
||||||
`int`, `string`, `uint64`, etc.). It takes a direction (`ASC` or `DESC`) as a
|
|
||||||
second argument. It does the directional sort based on that second argument.
|
|
||||||
|
|
||||||
```go
|
|
||||||
import (
|
|
||||||
"cmp"
|
|
||||||
"fmt"
|
|
||||||
"slices"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Direction int
|
|
||||||
|
|
||||||
const (
|
|
||||||
ASC Direction = iota
|
|
||||||
DESC
|
|
||||||
)
|
|
||||||
|
|
||||||
func SortItems[T cmp.Ordered](items []T, dir Direction) {
|
|
||||||
slices.SortFunc(items, func(i, j T) int {
|
|
||||||
if dir == ASC {
|
|
||||||
return cmp.Compare(i, j)
|
|
||||||
} else if dir == DESC {
|
|
||||||
return cmp.Compare(j, i)
|
|
||||||
} else {
|
|
||||||
panic(fmt.Sprintf("Unrecognized sort direction: %d", dir))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// items := []int{3,2,8,1}
|
|
||||||
// SortItems(items, ASC)
|
|
||||||
// // items => [1,2,3,8]
|
|
||||||
// SortItems(items, DESC)
|
|
||||||
// // items => [8,3,2,1]
|
|
||||||
```
|
|
||||||
|
|
||||||
Because `slices.SortFunc` expects a negative value, zero, or positive value to
|
|
||||||
determine the sort order, we use
|
|
||||||
[`cmp.Compare`](https://pkg.go.dev/cmp#Compare) which returns those kinds of
|
|
||||||
values. For ascending, we compare `i` to `j`. For descending, we swap them,
|
|
||||||
comparing `j` to `i` to get the reverse sort order.
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
# Disable Interpolation For A Heredoc String
|
|
||||||
|
|
||||||
As a matter of convenience, a heredoc performs string interpolation by default.
|
|
||||||
|
|
||||||
Here is an example of that.
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
irb(main):087> word = 'taco'
|
|
||||||
=> "taco"
|
|
||||||
irb(main):088" puts <<-TEXT
|
|
||||||
irb(main):089" I want to eat a #{word}!
|
|
||||||
irb(main):090> TEXT
|
|
||||||
I want to eat a taco!
|
|
||||||
=> nil
|
|
||||||
```
|
|
||||||
|
|
||||||
A much less common scenario is that we don't want string interpolation to take
|
|
||||||
place. For whatever reason, we want the exact string to be preserved. To
|
|
||||||
achieve that, we can wrap the opening heredoc identifier in single quotes.
|
|
||||||
|
|
||||||
As you can see, the `#{word}` portion is preserved.
|
|
||||||
|
|
||||||
```ruby
|
|
||||||
irb(main):091> word = 'taco'
|
|
||||||
=> "taco"
|
|
||||||
irb(main):092' puts <<-'TEXT'
|
|
||||||
irb(main):093' I want to eat a #{word}!
|
|
||||||
irb(main):094> TEXT
|
|
||||||
I want to eat a #{word}!
|
|
||||||
=> nil
|
|
||||||
```
|
|
||||||
|
|
||||||
This syntax puts the heredoc in single-quote mode. I left the IRB line preamble
|
|
||||||
in for each codeblock so that you can see the difference. The first example
|
|
||||||
(lines 88 and 89) shows the heredoc is double-quoted. The second example (lines
|
|
||||||
92 and 93) shows the heredoc is single quoted.
|
|
||||||
|
|
||||||
Note: the closing heredoc identifier (`TEXT` in this case) is not wrapped in
|
|
||||||
single quotes, just the opening one.
|
|
||||||
|
|
||||||
[source](https://ruby-doc.org/3.3.6/syntax/literals_rdoc.html#label-Here+Document+Literals)
|
|
||||||
Reference in New Issue
Block a user