lens_of_truth 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c683afe773d926b884d995ae7ff5bc05fec12f11
4
+ data.tar.gz: 289b22fef2d14618f33c9f9e75414d47f8dbca9c
5
+ SHA512:
6
+ metadata.gz: 0ed81aaf5eedbb77795e96d087d0539f38e030d501d866c65d606454a1b79bf073fe6d196989731c31c8e22f10012b5c2fa2d0ea03a315ab49243f587d2db21a
7
+ data.tar.gz: 2231dc06fd3cfb5efafdb4d7f94c5f3b97d08193b8bea926c74efbd797d5a82969f603ce7d4225961d3fb1c5e6bffb909ac97f1e5798665dca9a0950b7600803
data/CODE_OF_CONDUCT ADDED
@@ -0,0 +1,9 @@
1
+ ,---. ,---.-./`) ,---. .--. ____ .-'''-. .--. .--. ____ ,---. .--.
2
+ | \ / \ .-.')| \ | | .' __ `. / _ \| |_ | | .' __ `.| \ | |
3
+ | , \/ , / `-' \| , \ | |/ ' \ \ (`' )/`--'| _( )_ | |/ ' \ \ , \ | |
4
+ | |\_ /| |`-'`"`| |\_ \| ||___| / |(_ o _). |(_ o _) | ||___| / | |\_ \| |
5
+ | _( )_/ | |.---. | _( )_\ | _.-` | (_,_). '. | (_,_) \ | | _.-` | _( )_\ |
6
+ | (_ o _) | || | | (_ o _) |.' _ |.---. \ :| |/ \| |.' _ | (_ o _) |
7
+ | (_,_) | || | | (_,_)\ || _( )_ |\ `-' || ' /\ ` || _( )_ | (_,_)\ |
8
+ | | | || | | | | |\ (_ o _) / \ / | / \ |\ (_ o _) / | | |
9
+ '--' '--''---' '--' '--' '.(_,_).' `-...-' `---' `---` '.(_,_).''--' '--'
data/LICENSE ADDED
@@ -0,0 +1,13 @@
1
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2
+ Version 2, December 2004
3
+
4
+ Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
5
+
6
+ Everyone is permitted to copy and distribute verbatim or modified
7
+ copies of this license document, and changing it is allowed as long
8
+ as the name is changed.
9
+
10
+ DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION, AND MODIFICATION
12
+
13
+ 0. You just DO WHAT THE FUCK YOU WANT TO.
data/README.md ADDED
@@ -0,0 +1,60 @@
1
+ # ![Lens of Truth](http://i.imgur.com/iscFxKa.png) Lens of Truth
2
+
3
+ **lens_of_truth**, like [its namesake](http://zeldawiki.org/Lens_of_Truth), lets you find things the developers hid from you.
4
+
5
+ Operating on the assumption that related data tend to live reasonably close together in memory, `Object#find_nearby` looks up and down the heap from the receiver's address in search of an object which meets some specification.
6
+
7
+ ### "Use cases"
8
+
9
+ Under the hood, `Enumerator` is implemented in terms of fibers so as to support suspension and resumption. CRuby does the right thing by not exposing this implementation detail directly, but maybe we want a reference to the underlying `Fiber` anyway. We knows its [approximate location](https://git.io/vzNsN), so let's see if the **Lens of Truth** can help us home in on it:
10
+
11
+ ```ruby
12
+ require 'fiber' # for Fiber#transfer
13
+ require 'lens_of_truth'
14
+
15
+ using LensOfTruth # refinement
16
+
17
+ enum = Enumerator.new { |y|
18
+ y << y.find_nearby(Fiber) << 42
19
+ }
20
+ enum.next.transfer
21
+ enum.next # => cannot resume transferred Fiber (FiberError)
22
+ ```
23
+
24
+ Another extremely practical use for the Lens is to peek into the internals of lazy sequences.
25
+
26
+ ```ruby
27
+ [].lazy.map(&:succ).take(10)
28
+ # => #<Enumerator::Lazy: #<Enumerator::Lazy: #<Enumerator::Lazy: []>:map>:take(10)>
29
+ ```
30
+
31
+ Instances of `Enumerator::Lazy` clearly know their history, but they've hitherto been pretty hush-hush about it. In CRuby at least, they store [their method and arguments](https://git.io/vzN8H) in hidden instance variables (ones with no leading asperand and which are thus inaccessible from Ruby land). No matter: since an object's [instance variable table](https://git.io/vzNlq) is in the vicinity of the object itself, the **Lens of Truth** can help us find our way:
32
+
33
+ ```ruby
34
+ require 'lens_of_truth/core_ext' # patch Object directly
35
+
36
+ seq = [].lazy
37
+ seq = seq.map(&:succ)
38
+ seq.find_nearby(Proc).call(41) # => 42
39
+ seq = seq.take(10)
40
+ seq.find_nearby(Array) # => [10]
41
+ ```
42
+
43
+ Finding the right `Proc` or `Array` is a little harder (read: non-deterministic) since there are usually a lot of them about, but 60% of the time, it works every time.
44
+
45
+ ### Usage
46
+
47
+ `Object#find_nearby` uses case equality (`===`) when performing the search, so you can scan around for nearby strings matching some regular expression or a numeric object within a given range. You can instead pass a block to be used as the predicate. There's also an optional keyword argument `limit` which specifies how far to search in other direction before bailing. Examples follow.
48
+
49
+ ```ruby
50
+ p Object.find_nearby /^[A-Z]+$/
51
+ # => "DESTDIR"
52
+ p LensOfTruth.find_nearby 42..1337, limit: 9001
53
+ # => nil :(
54
+ p find_nearby { |o| o.is_a?(Hash) && o.size == 1 }
55
+ # => {:frozen_string_literal=>false} :)
56
+ ```
57
+
58
+ ### Contributing
59
+
60
+ Interesting use cases welcome.
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new :spec do |t|
4
+ t.test_files = ['spec/lens_of_truth_spec.rb']
5
+ end
6
+
7
+ task :default => :spec
@@ -0,0 +1,17 @@
1
+ $:.unshift File.expand_path '../lib', __FILE__
2
+ require 'lens_of_truth/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'lens_of_truth'
6
+ s.version = LensOfTruth::VERSION
7
+ s.author = 'D.E. Akers'
8
+ s.email = '0x0dea@gmail.com'
9
+
10
+ s.summary = 'Use the Lens of Truth to find objects hidden nearby.'
11
+ s.description = 'lens_of_truth adds Object#find_nearby to look around in proximal memory for things of interest.'
12
+
13
+ s.homepage = 'https://github.com/0x0dea/lens_of_truth'
14
+ s.license = 'WTFPL'
15
+
16
+ s.files = `git ls-files`.split
17
+ end
@@ -0,0 +1,3 @@
1
+ require 'lens_of_truth'
2
+
3
+ Object.include LensOfTruth
@@ -0,0 +1,3 @@
1
+ module LensOfTruth
2
+ VERSION = '0.1.0'
3
+ end
@@ -0,0 +1,25 @@
1
+ require 'fiddle'
2
+
3
+ module LensOfTruth
4
+ def find_nearby spec = Object, limit: Float::INFINITY
5
+ spec = proc if block_given?
6
+ found = nil
7
+ swivel = Fiddle::SIZEOF_UINTPTR_T / 2
8
+
9
+ [-swivel, swivel].map { |coef|
10
+ Thread.new do |i = 0|
11
+ until found || i > limit
12
+ begin
13
+ obj = ObjectSpace._id2ref __id__ + coef * i += 1
14
+ break found = obj if spec === obj
15
+ rescue RangeError
16
+ end
17
+ end
18
+ end
19
+ }.each &:join
20
+
21
+ found
22
+ end
23
+
24
+ refine(Object) { include LensOfTruth }
25
+ end
@@ -0,0 +1,49 @@
1
+ require 'minitest/autorun'
2
+ require 'minitest/pride'
3
+ require 'lens_of_truth'
4
+
5
+ using LensOfTruth
6
+
7
+ describe 'Object#find_nearby' do
8
+
9
+ it "should be able to find an Enumerator's underlying Fiber" do
10
+ require 'fiber'
11
+
12
+ enum = Enumerator.new { |y| y << y.find_nearby(Fiber) << 42 }
13
+ enum.next.transfer
14
+
15
+ e = -> { enum.next }.must_raise FiberError
16
+ e.message.must_match 'cannot resume transferred Fiber'
17
+ end
18
+
19
+ it "should be able to find a singleton class's attachee" do
20
+ obj = Object.new
21
+ cls = obj.singleton_class
22
+
23
+ cls.find_nearby { |o|
24
+ o.singleton_class == cls rescue nil
25
+ }.must_be_same_as obj
26
+ end
27
+
28
+ # NOTE: These next two are kinda flaky.
29
+
30
+ it "should be able to grab a lazy sequence's method" do
31
+ seq = [].lazy
32
+
33
+ foo = proc {} # Sprinkle the stack
34
+ seq = seq.map &:succ
35
+ bar = proc {} # for confusion.
36
+
37
+ seq.find_nearby(Proc).call(41).must_equal 42
38
+ end
39
+
40
+ it "should be able to grab a lazy sequence's arguments" do
41
+ seq = [].lazy
42
+
43
+ foo = [1,2,3] # More
44
+ seq = seq.take 10
45
+ bar = [4,5,6] # sprinkles.
46
+
47
+ seq.find_nearby(Array).must_equal [10]
48
+ end
49
+ end
metadata ADDED
@@ -0,0 +1,53 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lens_of_truth
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - D.E. Akers
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-01-29 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: lens_of_truth adds Object#find_nearby to look around in proximal memory
14
+ for things of interest.
15
+ email: 0x0dea@gmail.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - CODE_OF_CONDUCT
21
+ - LICENSE
22
+ - README.md
23
+ - Rakefile
24
+ - lens_of_truth.gemspec
25
+ - lib/lens_of_truth.rb
26
+ - lib/lens_of_truth/core_ext.rb
27
+ - lib/lens_of_truth/version.rb
28
+ - spec/lens_of_truth_spec.rb
29
+ homepage: https://github.com/0x0dea/lens_of_truth
30
+ licenses:
31
+ - WTFPL
32
+ metadata: {}
33
+ post_install_message:
34
+ rdoc_options: []
35
+ require_paths:
36
+ - lib
37
+ required_ruby_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ required_rubygems_version: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ requirements: []
48
+ rubyforge_project:
49
+ rubygems_version: 2.5.1
50
+ signing_key:
51
+ specification_version: 4
52
+ summary: Use the Lens of Truth to find objects hidden nearby.
53
+ test_files: []