Skip to content

Commit

Permalink
next iteration on reflection
Browse files Browse the repository at this point in the history
  • Loading branch information
quii committed Jun 30, 2018
1 parent 655e48e commit 1447214
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 3 deletions.
39 changes: 37 additions & 2 deletions reflection.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,42 @@ func walk(x interface{}, fn func(input string)) {
The test should now be passing. The next thing we'll need to do is make a more specific assertion on what our `fn` is being called with.

## Write the test first

Add the following to the existing test to check the string passed to `fn` is correct

```go
if got[0] != expected {
t.Errorf("got '%s', want '%s'", got[0], expected)
}
```

## Try to run the test
## Write the minimal amount of code for the test to run and check the failing test output

```
=== RUN TestWalk
--- FAIL: TestWalk (0.00s)
reflection_test.go:23: got 'I still can't believe South Korea beat Germany 2-0 to put them last in their group', want 'Chris'
FAIL
```

## Write enough code to make it pass
## Refactor

```go
func walk(x interface{}, fn func(input string)) {
val := reflect.ValueOf(x)
field := val.Field(0)
fn(field.String())
}
```

This code is _very unsafe and very naive_ but remember our goal when we are in "red" (the tests failing) is to write the smallest amount of code possible. We then write more tests to address our concerns.

We need to use reflection to have a look at `x` and try and look at its properties.

The [reflect package](https://godoc.org/reflect) has a function `ValueOf` which returns us a `Value` of a given variable. This has ways for us to inspect a value, including its fields which we use on the next line.

We then make some very silly assumptions about the the value passed in
- We look at the first and only field, there may be no fields at all which would cause a panic
- We then call `String()` which returns the underlying value as a string but we know it would be wrong if the field was something other than a string.


6 changes: 5 additions & 1 deletion reflection/v1/reflection.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package main

import "reflect"

func walk(x interface{}, fn func(input string)) {
fn("I still can't believe South Korea beat Germany 2-0 to put them last in their group")
val := reflect.ValueOf(x)
field := val.Field(0)
fn(field.String())
}
4 changes: 4 additions & 0 deletions reflection/v1/reflection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,8 @@ func TestWalk(t *testing.T) {
if len(got) != 1 {
t.Errorf("wrong number of function calls, got %d want %d", len(got), 1)
}

if got[0] != expected {
t.Errorf("got '%s', want '%s'", got[0], expected)
}
}

0 comments on commit 1447214

Please sign in to comment.