Module: FeatureEnvy::Inspect
- Defined in:
- lib/feature_envy/inspect.rb
Overview
Inspect method.
### Definition
The inspect method is a helper method, inspired by ‘inspect/2` in Elixir, aimed at making print debugging easier with minimal disruption to surrounding code.
### Applications
Quick inspection of intermediate values during development; **not intended for use in production**.
### Usage
-
Proceed with the remaining steps **only in non-production** environments.
-
Set an inspector by calling Inspect.inspector=. This is a method taking the object being inspected at as the argument and returning its string representation. You can use the built-in InspectInspector as the starting point.
-
Set an output by calling Inspect.output=. This is an object implementing ‘#puts` that will be called with the inspector result, so IO objects like `$stdout` and `$stderr` can be used.
-
Call inspect on objects you want to inspect at.
A custom inspector and output can be provided. The examples below have templates that can be used as starting points in development. There’s also an example showing how to enable the module in a Rails app.
### Discussion
Elixir makes it easy to print objects of interest, including intermediate ones, by passing them through ‘Kernel.inspect/2`. This function prints the object’s representation and returns the object itself, so that it can be called on intermediate results without disrupting the remaining instructions.
For example, the instruction below instantiates ‘Language`, prints its representation, and then passes that language to `Language.create!/1`:
“‘elixir %Language“Ruby” |>
inspect() |>
Language.create!()
“‘
Inspect is a Ruby counterpart of Elixir’s ‘inspect/2`. `#inspect!` was chosen since `#inspect` is already defined by Ruby and the `!` suffix indicates a “dangerous” method.
The syntax ‘object.inspect!` was chosen over `inspect!(object)` as it’s easier to insert in the middle of complicated method calls by requiring less modifications to the surrounding code. The difference is best illustrated in the following example:
“‘ruby # If we start with … User.create!(user_attributes(request))
# … then it’s easier to do to this … User.create!(user_attributes(request).inspect)
# … than this: User.create!(inspect(user_attributes(request))) “‘
### Implementation Notes
-
Refinement-based activation would require the developer to add ‘using FeatureEnvy::Inspect` before calling `inspect!`, which would be extremely inconvenient. Since the feature is intended for non-production use only monkey-patching is the only way to activate it.
Defined Under Namespace
Classes: Error, LoggerAdapter, NoInspectorError, NoOutputError
Constant Summary collapse
- InspectInspector =
An inspect-based inspector.
This is an inspector that calls ‘#inspect` on objects being inspected.
->(object) { object.inspect }
Class Attribute Summary collapse
-
.inspector ⇒ #call
The inspector converting objects to string representations.
-
.output ⇒ #puts
The output object sending inspection results to the developer.
Instance Method Summary collapse
-
#inspect! ⇒ self
Inspect the object and return it.
Class Attribute Details
.inspector ⇒ #call
The inspector converting objects to string representations.
The inspector must respond to ‘#call` with the object being inspected as the only argument, and must return a string, that will then be sent to output.
173 174 175 |
# File 'lib/feature_envy/inspect.rb', line 173 def inspector @inspector end |
.output ⇒ #puts
The output object sending inspection results to the developer.
The output object must respond to ‘#puts` with the string to print as its only argument. This implies all IO objects can be used, as well as custom classes implementing that interface.
184 185 186 |
# File 'lib/feature_envy/inspect.rb', line 184 def output @output end |
Instance Method Details
#inspect! ⇒ self
Inspect the object and return it.
The method inspects the object by:
1. Passing the object to `#inspect` defined on {.inspector}, producing a
string representation of the object.
2. Passing that string to `#puts` defined on {.output}.
151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/feature_envy/inspect.rb', line 151 def inspect! if FeatureEnvy::Inspect.inspector.nil? raise NoInspectorError.new end if FeatureEnvy::Inspect.output.nil? raise NoOutputError.new end result = FeatureEnvy::Inspect.inspector.call self FeatureEnvy::Inspect.output.puts result self end |