Skip to content

Commit cdab341

Browse files
committed
docs: add second inspection listing
Add listing-002.md exploring Kernel patches, CLI script, and gemspec for Fagan inspection.
1 parent 0829ac6 commit cdab341

File tree

1 file changed

+185
-0
lines changed

1 file changed

+185
-0
lines changed

listing-002.md

Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
# Listing 002
2+
3+
This listing continues the inspection by detailing how runtime I/O is captured and how the gem is packaged. We review the output-hooking helpers in `gems/codetracer-ruby-recorder/lib/codetracer/kernel_patches.rb`, the CLI entry script `gems/codetracer-ruby-recorder/bin/codetracer-ruby-recorder`, and the gem specification `gems/codetracer-ruby-recorder/codetracer-ruby-recorder.gemspec`.
4+
5+
**File declares MIT license and begins KernelPatches module tracking installed tracers.**
6+
```ruby
7+
# SPDX-License-Identifier: MIT
8+
9+
module CodeTracer
10+
module KernelPatches
11+
@@tracers = []
12+
```
13+
14+
**Add a tracer unless already present and store it in the class variable.**
15+
```ruby
16+
def self.install(tracer)
17+
return if @@tracers.include?(tracer)
18+
@@tracers << tracer
19+
```
20+
21+
**When the first tracer is installed, patch Kernel methods.**
22+
```ruby
23+
if @@tracers.length == 1
24+
Kernel.module_eval do
25+
```
26+
27+
**Alias original I/O methods so they can be restored later.**
28+
```ruby
29+
alias_method :codetracer_original_p, :p unless method_defined?(:codetracer_original_p)
30+
alias_method :codetracer_original_puts, :puts unless method_defined?(:codetracer_original_puts)
31+
alias_method :codetracer_original_print, :print unless method_defined?(:codetracer_original_print)
32+
```
33+
34+
**Redefine `p` to compute a printable representation and log it.**
35+
```ruby
36+
define_method(:p) do |*args|
37+
loc = caller_locations(1, 1).first
38+
content = if args.length == 1 && args.first.is_a?(Array)
39+
```
40+
41+
**Handle array arguments or multiple values uniformly.**
42+
```ruby
43+
args.first.map(&:inspect).join("\n")
44+
else
45+
args.map(&:inspect).join("\n")
46+
end
47+
```
48+
49+
**Record the event with all active tracers before delegating.**
50+
```ruby
51+
@@tracers.each do |t|
52+
t.record_event(loc.path, loc.lineno, content)
53+
end
54+
codetracer_original_p(*args)
55+
end
56+
```
57+
58+
**Redefine `puts` to capture line-oriented output.**
59+
```ruby
60+
define_method(:puts) do |*args|
61+
loc = caller_locations(1, 1).first
62+
@@tracers.each do |t|
63+
t.record_event(loc.path, loc.lineno, args.join("\n"))
64+
end
65+
```
66+
67+
**Forward `puts` after logging the captured lines.**
68+
```ruby
69+
codetracer_original_puts(*args)
70+
end
71+
```
72+
73+
**Redefine `print` to intercept raw output without newlines.**
74+
```ruby
75+
define_method(:print) do |*args|
76+
loc = caller_locations(1, 1).first
77+
@@tracers.each do |t|
78+
t.record_event(loc.path, loc.lineno, args.join)
79+
end
80+
```
81+
82+
**Delegate `print` to the original implementation afterward.**
83+
```ruby
84+
codetracer_original_print(*args)
85+
end
86+
end
87+
end
88+
end
89+
```
90+
91+
**Remove a tracer and restore Kernel methods when none remain.**
92+
```ruby
93+
def self.uninstall(tracer)
94+
@@tracers.delete(tracer)
95+
96+
if @@tracers.empty? && Kernel.private_method_defined?(:codetracer_original_p)
97+
Kernel.module_eval do
98+
alias_method :p, :codetracer_original_p
99+
alias_method :puts, :codetracer_original_puts
100+
alias_method :print, :codetracer_original_print
101+
end
102+
end
103+
end
104+
```
105+
106+
**Provide helper to uninstall every active tracer.**
107+
```ruby
108+
# Uninstall all active tracers and restore the original Kernel methods.
109+
def self.reset
110+
@@tracers.dup.each do |tracer|
111+
uninstall(tracer)
112+
end
113+
end
114+
end
115+
end
116+
```
117+
118+
**Shebang, license, and comment establish the CLI script.**
119+
```ruby
120+
#!/usr/bin/env ruby
121+
# SPDX-License-Identifier: MIT
122+
# CLI wrapper for the native tracer
123+
```
124+
125+
**Load the library path and require the main recorder.**
126+
```ruby
127+
lib_dir = File.expand_path('../lib', __dir__)
128+
$LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
129+
require 'codetracer_ruby_recorder'
130+
```
131+
132+
**Invoke the argument parser and exit with its status.**
133+
```ruby
134+
exit CodeTracer::RubyRecorder.parse_argv_and_trace_ruby_file(ARGV)
135+
```
136+
137+
**Begin gem specification and compute version from file.**
138+
```ruby
139+
Gem::Specification.new do |spec|
140+
spec.name = 'codetracer-ruby-recorder'
141+
version_file = File.expand_path('../../version.txt', __dir__)
142+
spec.version = File.read(version_file).strip
143+
```
144+
145+
**Define authorship metadata for the gem.**
146+
```ruby
147+
spec.authors = ['Metacraft Labs']
148+
spec.email = ['[email protected]']
149+
```
150+
151+
**Provide summary, description, license, and homepage.**
152+
```ruby
153+
spec.summary = 'CodeTracer Ruby recorder with native extension'
154+
spec.description = 'Ruby tracer that records execution steps via a Rust native extension.'
155+
spec.license = 'MIT'
156+
spec.homepage = 'https://github.com/metacraft-labs/codetracer-ruby-recorder'
157+
```
158+
159+
**Enumerate files to include in the gem package.**
160+
```ruby
161+
spec.files = Dir[
162+
'lib/**/*',
163+
'ext/native_tracer/**/{Cargo.toml,*.rs}',
164+
```
165+
166+
**List native extension build scripts and compiled targets.**
167+
```ruby
168+
'ext/native_tracer/extconf.rb',
169+
'ext/native_tracer/target/release/*'
170+
]
171+
```
172+
173+
**Configure load paths, extensions, and executable entrypoint.**
174+
```ruby
175+
spec.require_paths = ['lib']
176+
spec.extensions = []
177+
spec.bindir = 'bin'
178+
spec.executables = ['codetracer-ruby-recorder']
179+
```
180+
181+
**Add development dependency on rb_sys and close specification.**
182+
```ruby
183+
spec.add_development_dependency 'rb_sys', '~> 0.9'
184+
end
185+
```

0 commit comments

Comments
 (0)