Skip to content

Instantly share code, notes, and snippets.

@joshrowley
Created September 21, 2016 15:35
Show Gist options
  • Save joshrowley/662ee1deb05ba554de5fdcd1f2fda86e to your computer and use it in GitHub Desktop.
Save joshrowley/662ee1deb05ba554de5fdcd1f2fda86e to your computer and use it in GitHub Desktop.

Confident Ruby Ch. 3 Notes

3. Collecting Input

  • "It is possible for a method to receive no input whatsoever, but such methods don't usually accomplish much."
  • "an explicit class name is an input like any other. It's information that comes from outside the method."

Indirect Inputs

  • "Any time we send a message to an object other than self in order to use its return value, we're using indirect inputs." (Time.now)
    • more levels of indirection == more fragile code
    • indirect input...another word for dependencies?
  • "This situation, where one input value is used to help fetch another, is one of the richest sources of surprises (aka "bugs") in software."
  • Input collection stanza.
    • Do we recognize this pattern in the code we write?
    • What are the benefits of this idiom? (intentional identification of inputs both direct and indirect == identifying and evaluating dependencies) Can lead to easier recognition when a method or object "knows too much"
  • Inputs need to be reliable in their roles. 3 Strategies:
    • Coerce objects into their roles
    • Reject unexpected values that cannot fulfill the role
    • Substitute known good objects for unacceptable inputs
  • "Guard the borders not the hinterlands"
    • You can overkill it with the defensive code for checking inputs
    • Evaluate the tradeoffs
      • how much do we trust our input?
        • only my nearby collaborator code relies on it? less necessary
        • public API in library, need more defensive checks
        • Interface between two different submodules
      • "object neighborhoods" and subsystems

Use built in conversion protocols

  • @avdi++ for homestar examples
  • to_str, to_i, to_path, to_ary
  • leverage ruby's built in coercion when calling array[i] by defining a to_int method for i
  • another example: File.open('some path'), you can pass in an object as well if you define to_path on it to return the file path you want to open for the object
  • Any examples in our codebase that could benefit?
    • Lesson#to_i => github id
    • learn gem =>
  • "By stating their needs clearly in the form of calls to conversion methods, standard library methods are able to interact with any objects which respond to those methods." Duck Typing!!
  • Any negatives we can think of to this?
    • Conditional checks within the callee's method implementation kinda seems like it could become a nasty issue if the method stops supporting it.
    • How much can you depend on the coercion? Should library maintainers express these things in their specs, in the docs, as part of the public API?
    • Implicit dependency
    • Callee method should give clear error messaging if this is attempted but unsuccessful
  • Explicit vs Implicit conversion methods
    • btw, who decided all this?
    • How to determine if an object is "similar" to the target coercion object
    • concat strings => good example of implicit coercion
    • "But the value of #to_str lies in the fact that pretty much everywhere Ruby core classes expect to get a String, they implicitly send the #to_str message to the input object (hence the term "implicit conversion")."
    • ArticleTitle example
      • is it overkill?
      • or is it pretty awesome (think how easily we can change say Lesson#title to be an object with slug method and can be extensible, yet still behave completely like a string since all our existing code thinks its just a string)
      • could be interesting way to cut down on display helper methods and instead create "smart string classes" for some of our model attributes
      • string interpolation calls to_s
        • devil's advocate, knowing these small details of the lang can create "clever" code, can this ever be detrimental in a team. (just because a language has a feature should you always use it if not many others understand it)
        • ruby philosophy? least surprise principle (whose opinion determines that?)
      • "Here the implicit conversion call serves as an assertion, ensuring the method receives an argument which is either an Integer or an object with a well-deWned conversion to Integer" oh snap programatic programmer up in here

Conditionally Call Conversion methods

  • Make the call to a conversion method conditional on whether the object can respond to that method.
  • Violating ducktyping (avdi gives lots of examples but not much reasoning)
    • Are you asking details about the object to check if it's valid input? Prob ok to violate
    • Are you asking details about the object to perform work on its behalf? Prob not ok

Other discussion

  • Something to think about, why is collecting input is so much larger in the book structure than anything else? Possible answers:
    • Writing software is mainly about managing complexity. Complexity increases as dependencies increase. Your dependencies are your input, and what "role" they play. Collecting input is the process of analyzing and evaluating your inputs/dependencies with intention and a critical eye. This is one of the largest influences in having a happy, productive, maintainable codebase.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment