meta_instance 1.0.2 → 1.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 +4 -4
 - data/.codeclimate.yml +7 -0
 - data/.gitignore +33 -16
 - data/.travis.yml +8 -4
 - data/Gemfile +2 -3
 - data/Gemfile.lock +66 -0
 - data/HISTORY.md +33 -0
 - data/LICENSE.txt +23 -0
 - data/README.md +56 -25
 - data/docs/instance.md +201 -0
 - data/docs/module.md +34 -0
 - data/lib/meta_instance.rb +32 -53
 - data/lib/meta_instance/freeze_method.rb +13 -0
 - data/lib/meta_instance/instance_method_define.rb +61 -0
 - data/lib/meta_instance/module_extensions.rb +61 -0
 - data/lib/meta_instance/proxy.rb +270 -0
 - data/lib/meta_instance/version.rb +2 -2
 - data/meta_instance.gemspec +4 -3
 - data/spec/instance_spec.rb +123 -0
 - data/spec/{meta_instance_spec.rb → meta_instance/instance_method_define_spec.rb} +22 -15
 - data/spec/module_spec.rb +0 -0
 - data/spec/spec_helper.rb +1 -3
 - metadata +35 -11
 - data/.rspec +0 -2
 - data/LICENSE +0 -22
 - data/Rakefile +0 -1
 - data/spec/support/foo.rb +0 -5
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA1:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: b5ac0a81bfddb2ae4fbf907fa143708453c7d0e9
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 5a1caa2e9320ac41222b9ba149a1e7c5aec0c61d
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: fa17b965044435b3f57dd1b2c2b8a04fa5d60d827a973907b229e214725389228ef688f2c2b7a31c7ab449b416773b72746219d1646de685680fec40964befd0
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 8a5f58deae6e2e3dae92c2a3812e25af21d2730b380de4753cc29c8c7ce9a8073b3fbfaaeb6498f0b794d9cfbfda06bfcb8470d54432be6c7afe8b2f50be6f84
         
     | 
    
        data/.codeclimate.yml
    ADDED
    
    
    
        data/.gitignore
    CHANGED
    
    | 
         @@ -1,18 +1,35 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            *.gem
         
     | 
| 
       2 
2 
     | 
    
         
             
            *.rbc
         
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
             
     | 
| 
       9 
     | 
    
         
            -
             
     | 
| 
       10 
     | 
    
         
            -
             
     | 
| 
       11 
     | 
    
         
            -
             
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
       17 
     | 
    
         
            -
             
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
      
 3 
     | 
    
         
            +
            /.config
         
     | 
| 
      
 4 
     | 
    
         
            +
            /coverage/
         
     | 
| 
      
 5 
     | 
    
         
            +
            /InstalledFiles
         
     | 
| 
      
 6 
     | 
    
         
            +
            /pkg/
         
     | 
| 
      
 7 
     | 
    
         
            +
            /spec/reports/
         
     | 
| 
      
 8 
     | 
    
         
            +
            /test/tmp/
         
     | 
| 
      
 9 
     | 
    
         
            +
            /test/version_tmp/
         
     | 
| 
      
 10 
     | 
    
         
            +
            /tmp/
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            ## Specific to RubyMotion:
         
     | 
| 
      
 13 
     | 
    
         
            +
            .dat*
         
     | 
| 
      
 14 
     | 
    
         
            +
            .repl_history
         
     | 
| 
      
 15 
     | 
    
         
            +
            build/
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            ## Documentation cache and generated files:
         
     | 
| 
      
 18 
     | 
    
         
            +
            /.yardoc/
         
     | 
| 
      
 19 
     | 
    
         
            +
            /_yardoc/
         
     | 
| 
      
 20 
     | 
    
         
            +
            /doc/
         
     | 
| 
      
 21 
     | 
    
         
            +
            /rdoc/
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
            ## Environment normalisation:
         
     | 
| 
      
 24 
     | 
    
         
            +
            /.bundle/
         
     | 
| 
      
 25 
     | 
    
         
            +
            /vendor/bundle
         
     | 
| 
      
 26 
     | 
    
         
            +
            /lib/bundler/man/
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            # for a library or gem, you might want to ignore these files since the code is
         
     | 
| 
      
 29 
     | 
    
         
            +
            # intended to run in multiple environments; otherwise, check them in:
         
     | 
| 
      
 30 
     | 
    
         
            +
            # Gemfile.lock
         
     | 
| 
      
 31 
     | 
    
         
            +
            # .ruby-version
         
     | 
| 
      
 32 
     | 
    
         
            +
            # .ruby-gemset
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
         
     | 
| 
      
 35 
     | 
    
         
            +
            .rvmrc
         
     | 
    
        data/.travis.yml
    CHANGED
    
    | 
         @@ -1,13 +1,17 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            language: ruby
         
     | 
| 
       2 
2 
     | 
    
         
             
            bundler_args: --without guard
         
     | 
| 
       3 
3 
     | 
    
         
             
            rvm:
         
     | 
| 
       4 
     | 
    
         
            -
              -  
     | 
| 
       5 
     | 
    
         
            -
              -  
     | 
| 
      
 4 
     | 
    
         
            +
              - 2.0.0
         
     | 
| 
      
 5 
     | 
    
         
            +
              - 2.2
         
     | 
| 
       6 
6 
     | 
    
         
             
              - ruby-head
         
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
      
 7 
     | 
    
         
            +
            matrix:
         
     | 
| 
      
 8 
     | 
    
         
            +
              allow_failures:
         
     | 
| 
      
 9 
     | 
    
         
            +
                - rvm:
         
     | 
| 
      
 10 
     | 
    
         
            +
                  - ruby-head
         
     | 
| 
      
 11 
     | 
    
         
            +
            script: bundle exec rspec
         
     | 
| 
       8 
12 
     | 
    
         
             
            addons:
         
     | 
| 
       9 
13 
     | 
    
         
             
              code_climate:
         
     | 
| 
       10 
     | 
    
         
            -
                repo_token:  
     | 
| 
      
 14 
     | 
    
         
            +
                repo_token: "97758529c5c06792d2f683e15e6ffe819ac16d140fe244640dcf103f1d172fc4 "
         
     | 
| 
       11 
15 
     | 
    
         
             
            branches:
         
     | 
| 
       12 
16 
     | 
    
         
             
              only: master
         
     | 
| 
       13 
17 
     | 
    
         
             
            notifications:
         
     | 
    
        data/Gemfile
    CHANGED
    
    
    
        data/Gemfile.lock
    ADDED
    
    | 
         @@ -0,0 +1,66 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            PATH
         
     | 
| 
      
 2 
     | 
    
         
            +
              remote: .
         
     | 
| 
      
 3 
     | 
    
         
            +
              specs:
         
     | 
| 
      
 4 
     | 
    
         
            +
                meta_instance (1.1.0)
         
     | 
| 
      
 5 
     | 
    
         
            +
                  activesupport
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            GEM
         
     | 
| 
      
 8 
     | 
    
         
            +
              remote: https://rubygems.org/
         
     | 
| 
      
 9 
     | 
    
         
            +
              specs:
         
     | 
| 
      
 10 
     | 
    
         
            +
                activesupport (4.2.1)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  i18n (~> 0.7)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  json (~> 1.7, >= 1.7.7)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  minitest (~> 5.1)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  thread_safe (~> 0.3, >= 0.3.4)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  tzinfo (~> 1.1)
         
     | 
| 
      
 16 
     | 
    
         
            +
                byebug (4.0.5)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  columnize (= 0.9.0)
         
     | 
| 
      
 18 
     | 
    
         
            +
                codeclimate-test-reporter (0.4.7)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  simplecov (>= 0.7.1, < 1.0.0)
         
     | 
| 
      
 20 
     | 
    
         
            +
                coderay (1.1.0)
         
     | 
| 
      
 21 
     | 
    
         
            +
                columnize (0.9.0)
         
     | 
| 
      
 22 
     | 
    
         
            +
                diff-lcs (1.2.5)
         
     | 
| 
      
 23 
     | 
    
         
            +
                docile (1.1.5)
         
     | 
| 
      
 24 
     | 
    
         
            +
                i18n (0.7.0)
         
     | 
| 
      
 25 
     | 
    
         
            +
                json (1.8.2)
         
     | 
| 
      
 26 
     | 
    
         
            +
                method_source (0.8.2)
         
     | 
| 
      
 27 
     | 
    
         
            +
                minitest (5.6.1)
         
     | 
| 
      
 28 
     | 
    
         
            +
                pry (0.10.1)
         
     | 
| 
      
 29 
     | 
    
         
            +
                  coderay (~> 1.1.0)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  method_source (~> 0.8.1)
         
     | 
| 
      
 31 
     | 
    
         
            +
                  slop (~> 3.4)
         
     | 
| 
      
 32 
     | 
    
         
            +
                pry-byebug (3.1.0)
         
     | 
| 
      
 33 
     | 
    
         
            +
                  byebug (~> 4.0)
         
     | 
| 
      
 34 
     | 
    
         
            +
                  pry (~> 0.10)
         
     | 
| 
      
 35 
     | 
    
         
            +
                rspec (3.2.0)
         
     | 
| 
      
 36 
     | 
    
         
            +
                  rspec-core (~> 3.2.0)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  rspec-expectations (~> 3.2.0)
         
     | 
| 
      
 38 
     | 
    
         
            +
                  rspec-mocks (~> 3.2.0)
         
     | 
| 
      
 39 
     | 
    
         
            +
                rspec-core (3.2.3)
         
     | 
| 
      
 40 
     | 
    
         
            +
                  rspec-support (~> 3.2.0)
         
     | 
| 
      
 41 
     | 
    
         
            +
                rspec-expectations (3.2.1)
         
     | 
| 
      
 42 
     | 
    
         
            +
                  diff-lcs (>= 1.2.0, < 2.0)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  rspec-support (~> 3.2.0)
         
     | 
| 
      
 44 
     | 
    
         
            +
                rspec-mocks (3.2.1)
         
     | 
| 
      
 45 
     | 
    
         
            +
                  diff-lcs (>= 1.2.0, < 2.0)
         
     | 
| 
      
 46 
     | 
    
         
            +
                  rspec-support (~> 3.2.0)
         
     | 
| 
      
 47 
     | 
    
         
            +
                rspec-support (3.2.2)
         
     | 
| 
      
 48 
     | 
    
         
            +
                simplecov (0.10.0)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  docile (~> 1.1.0)
         
     | 
| 
      
 50 
     | 
    
         
            +
                  json (~> 1.8)
         
     | 
| 
      
 51 
     | 
    
         
            +
                  simplecov-html (~> 0.10.0)
         
     | 
| 
      
 52 
     | 
    
         
            +
                simplecov-html (0.10.0)
         
     | 
| 
      
 53 
     | 
    
         
            +
                slop (3.6.0)
         
     | 
| 
      
 54 
     | 
    
         
            +
                thread_safe (0.3.5)
         
     | 
| 
      
 55 
     | 
    
         
            +
                tzinfo (1.2.2)
         
     | 
| 
      
 56 
     | 
    
         
            +
                  thread_safe (~> 0.1)
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
            PLATFORMS
         
     | 
| 
      
 59 
     | 
    
         
            +
              ruby
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
            DEPENDENCIES
         
     | 
| 
      
 62 
     | 
    
         
            +
              bundler
         
     | 
| 
      
 63 
     | 
    
         
            +
              codeclimate-test-reporter
         
     | 
| 
      
 64 
     | 
    
         
            +
              meta_instance!
         
     | 
| 
      
 65 
     | 
    
         
            +
              pry-byebug
         
     | 
| 
      
 66 
     | 
    
         
            +
              rspec
         
     | 
    
        data/HISTORY.md
    ADDED
    
    | 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # RELEASE HISTORY
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            ## 1.1.0 | 2015-05-27
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            This release prepares for gemification.
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            Changes:
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
            * Add RSpec Tests
         
     | 
| 
      
 10 
     | 
    
         
            +
            * Prep for gem publishing
         
     | 
| 
      
 11 
     | 
    
         
            +
            * Merge code with NullVoxPopuli/meta_instance
         
     | 
| 
      
 12 
     | 
    
         
            +
            * New Architecture
         
     | 
| 
      
 13 
     | 
    
         
            +
            * Rename to MetaInstance, replacing existing meta_instance gem
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            ## 0.2.0 | 2014-02-02
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
            This release adds an extra set of methods for modules and classes.
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            Changes:
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
            * Add `method_definition` if object is a module or class.
         
     | 
| 
      
 23 
     | 
    
         
            +
            * Add `method_definitions` if object is a module or class.
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            ## 0.1.0 | 2014-02-01
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            This is the initial release of Instance, a class spun-off from
         
     | 
| 
      
 29 
     | 
    
         
            +
            Ruby Facets.
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            Changes:
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
            * Happy Release Day!
         
     | 
    
        data/LICENSE.txt
    ADDED
    
    | 
         @@ -0,0 +1,23 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            BSD-2-Clause License (http://spdx.org/licenses/BSD-2-Clause)
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Redistribution and use in source and binary forms, with or without modification, are
         
     | 
| 
      
 4 
     | 
    
         
            +
            permitted provided that the following conditions are met:
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
               1. Redistributions of source code must retain the above copyright notice, this list of
         
     | 
| 
      
 7 
     | 
    
         
            +
                  conditions and the following disclaimer.
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
               2. Redistributions in binary form must reproduce the above copyright notice, this list
         
     | 
| 
      
 10 
     | 
    
         
            +
                  of conditions and the following disclaimer in the documentation and/or other materials
         
     | 
| 
      
 11 
     | 
    
         
            +
                  provided with the distribution.
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
            THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESS OR IMPLIED
         
     | 
| 
      
 14 
     | 
    
         
            +
            WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
         
     | 
| 
      
 15 
     | 
    
         
            +
            FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
         
     | 
| 
      
 16 
     | 
    
         
            +
            OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
         
     | 
| 
      
 17 
     | 
    
         
            +
            CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
         
     | 
| 
      
 18 
     | 
    
         
            +
            SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
         
     | 
| 
      
 19 
     | 
    
         
            +
            ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
         
     | 
| 
      
 20 
     | 
    
         
            +
            NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
         
     | 
| 
      
 21 
     | 
    
         
            +
            ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
    
        data/README.md
    CHANGED
    
    | 
         @@ -1,42 +1,73 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            MetaInstance
         
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
      
 2 
     | 
    
         
            +
            ========
         
     | 
| 
      
 3 
     | 
    
         
            +
            [](http://badge.fury.io/rb/meta_instance)
         
     | 
| 
      
 4 
     | 
    
         
            +
            [](https://travis-ci.org/NullVoxPopuli/MetaInstance)
         
     | 
| 
      
 5 
     | 
    
         
            +
            [](https://codeclimate.com/github/NullVoxPopuli/MetaInstance)
         
     | 
| 
      
 6 
     | 
    
         
            +
            [](https://codeclimate.com/github/NullVoxPopuli/MetaInstance)
         
     | 
| 
      
 7 
     | 
    
         
            +
            [](https://gemnasium.com/NullVoxPopuli/MetaInstance)
         
     | 
| 
       3 
8 
     | 
    
         | 
| 
       4 
     | 
    
         
            -
            [](http://badge.fury.io/rb/meta_instance)
         
     | 
| 
       5 
     | 
    
         
            -
            [](https://travis-ci.org/NullVoxPopuli/MetaInstance)
         
     | 
| 
       6 
     | 
    
         
            -
            [](https://codeclimate.com/github/NullVoxPopuli/MetaInstance)
         
     | 
| 
       7 
     | 
    
         
            -
            [](https://codeclimate.com/github/NullVoxPopuli/MetaInstance)
         
     | 
| 
       8 
     | 
    
         
            -
            [](https://gemnasium.com/NullVoxPopuli/MetaInstance)
         
     | 
| 
       9 
     | 
    
         
            -
            [](https://hakiri.io/github/NullVoxPopuli/MetaInstance/master)
         
     | 
| 
       10 
9 
     | 
    
         | 
| 
       11 
     | 
    
         
            -
            A few helpers for manipulating methods on an instance of an object.
         
     | 
| 
       12 
10 
     | 
    
         | 
| 
      
 11 
     | 
    
         
            +
            ## What Is It?
         
     | 
| 
       13 
12 
     | 
    
         | 
| 
       14 
     | 
    
         
            -
             
     | 
| 
      
 13 
     | 
    
         
            +
            MetaInstance is a *convenient* and *safe* API for accessing and manipulating
         
     | 
| 
      
 14 
     | 
    
         
            +
            an object's state.
         
     | 
| 
       15 
15 
     | 
    
         | 
| 
       16 
     | 
    
         
            -
             
     | 
| 
      
 16 
     | 
    
         
            +
            ## How Does It Work
         
     | 
| 
       17 
17 
     | 
    
         | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
      
 18 
     | 
    
         
            +
            MetaInstance adds a method to all objects called `#instance`. It returns
         
     | 
| 
      
 19 
     | 
    
         
            +
            an `Instance` delegator that provides the full interface to the
         
     | 
| 
      
 20 
     | 
    
         
            +
            object's state.
         
     | 
| 
       19 
21 
     | 
    
         | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
      
 22 
     | 
    
         
            +
            Of course, without implementing this in C, directly in the Ruby source,
         
     | 
| 
      
 23 
     | 
    
         
            +
            we  are left to depend on the current provisions Ruby has for accessing
         
     | 
| 
      
 24 
     | 
    
         
            +
            the state of an object. So there are some limitations here. However,
         
     | 
| 
      
 25 
     | 
    
         
            +
            we implement the Ruby code in such a way as to minimize the downsides
         
     | 
| 
      
 26 
     | 
    
         
            +
            by caching all the method definitions the Instance class will utilize.
         
     | 
| 
       21 
27 
     | 
    
         | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
       23 
     | 
    
         
            -
                  include MetaInstance
         
     | 
| 
      
 28 
     | 
    
         
            +
            ## Usage
         
     | 
| 
       24 
29 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
      
 30 
     | 
    
         
            +
            Let's use a very simple example class with which to demonstrate usage.
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 33 
     | 
    
         
            +
                class Song
         
     | 
| 
      
 34 
     | 
    
         
            +
                  attr_accessor :title
         
     | 
| 
      
 35 
     | 
    
         
            +
                  attr_accessor :artist
         
     | 
| 
      
 36 
     | 
    
         
            +
                  attr_accessor :year
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  def initialize(title, artist, year)
         
     | 
| 
      
 39 
     | 
    
         
            +
                    @title  = title
         
     | 
| 
      
 40 
     | 
    
         
            +
                    @artist = artist
         
     | 
| 
      
 41 
     | 
    
         
            +
                    @year   = year
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
       26 
43 
     | 
    
         
             
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
            ```
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
            Now we can create an instance of Song and work with it's state.
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            ```ruby
         
     | 
| 
      
 49 
     | 
    
         
            +
                song = Song.new("Paranoid", "Black Sabbath", 1970)
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
                song.instance.variables
         
     | 
| 
      
 52 
     | 
    
         
            +
                # => [:@title, :@artist, :@year]
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                song.instance.get(:title)
         
     | 
| 
      
 55 
     | 
    
         
            +
                # => "Paranoid"
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
                song.instance[:artist]
         
     | 
| 
      
 58 
     | 
    
         
            +
                # => "Black Sabbath"
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
                song.instance.to_h
         
     | 
| 
      
 61 
     | 
    
         
            +
                # => {:title => "Paranoid", :artist => "Black Sabbath", :year => 1970}
         
     | 
| 
      
 62 
     | 
    
         
            +
            ```
         
     | 
| 
       27 
63 
     | 
    
         | 
| 
       28 
     | 
    
         
            -
             
     | 
| 
      
 64 
     | 
    
         
            +
            For a more complete set of usage examples see the [QED](http://rubyworks.github.com/instance/qed.html) documentation.
         
     | 
| 
       29 
65 
     | 
    
         | 
| 
       30 
     | 
    
         
            -
                f = Foo.new
         
     | 
| 
       31 
     | 
    
         
            -
                f.bar
         
     | 
| 
       32 
     | 
    
         
            -
                # => "bar"
         
     | 
| 
       33 
66 
     | 
    
         | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
                f.bar
         
     | 
| 
       36 
     | 
    
         
            -
                # => "foo"
         
     | 
| 
      
 67 
     | 
    
         
            +
            ## Copyrights
         
     | 
| 
       37 
68 
     | 
    
         | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
       39 
     | 
    
         
            -
                # => "bar"
         
     | 
| 
      
 69 
     | 
    
         
            +
            Copyright © 2014 [Rubyworks](http://rubyworks.github.io)
         
     | 
| 
       40 
70 
     | 
    
         | 
| 
      
 71 
     | 
    
         
            +
            BSD-2-Clause License
         
     | 
| 
       41 
72 
     | 
    
         | 
| 
       42 
     | 
    
         
            -
            See  
     | 
| 
      
 73 
     | 
    
         
            +
            See [LICENSE.txt](LICENSE.txt) file for license details.
         
     | 
    
        data/docs/instance.md
    ADDED
    
    | 
         @@ -0,0 +1,201 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # Instance
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            First thing we need to do, of course, is load the library.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                require 'instance'
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            Now we can create an example class with which to work.
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                class ::Friend
         
     | 
| 
      
 10 
     | 
    
         
            +
                  attr_accessor :name, :age, :phone
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                  def initialize(name, age, phone)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    @name, @age, @phone = name, age, phone
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
            And now demonstrate the available API.
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            ## Instance#variables
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
            A list of instance variables can be had via the `#variables` method.
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                f = Friend.new("John", 30, "555-1212")
         
     | 
| 
      
 24 
     | 
    
         
            +
                f.instance.variables.assert == [:@name, :@age, :@phone]
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
            ## Instance#names
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
            To get a list of variables names as strings and without the `@` prefix,
         
     | 
| 
      
 29 
     | 
    
         
            +
            use the `#names` method.
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                f = Friend.new("John", 30, "555-1212")
         
     | 
| 
      
 32 
     | 
    
         
            +
                f.instance.names.assert == ["name", "age", "phone"]
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
            ## Instance#keys
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
            Likewise, to get symbols instead of strings, use the `#keys` method.
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                f = Friend.new("John", 30, "555-1212")
         
     | 
| 
      
 39 
     | 
    
         
            +
                f.instance.keys.assert == [:name, :age, :phone]
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            ## Instance#values
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            The values of the instance variables alone can be had via the `#values` method.
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                f = Friend.new("John", 30, "555-1212")
         
     | 
| 
      
 46 
     | 
    
         
            +
                f.instance.values.assert == ["John", 30, "555-1212"]
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
            ## Instance#size
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            The `#size` method reports how many instance variables are defined.
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                f = Friend.new("John", 30, "555-1212")
         
     | 
| 
      
 53 
     | 
    
         
            +
                f.instance.size.assert == 3
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
            This method is primarily of use to the Enumerable mixin.
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
            ## Instance#variable_defined?
         
     | 
| 
      
 58 
     | 
    
         
            +
             
     | 
| 
      
 59 
     | 
    
         
            +
                f = Friend.new("John", 30, "555-1212")
         
     | 
| 
      
 60 
     | 
    
         
            +
                f.instance.assert.variable_defined?(:@name)
         
     | 
| 
      
 61 
     | 
    
         
            +
                f.instance.assert.variable_defined?(:name)
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
            ## Instance#update
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
            The `#update` method can be used to change instance variables in mass via
         
     | 
| 
      
 66 
     | 
    
         
            +
            method options.
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                f = Friend.new("John", 30, "555-1212")
         
     | 
| 
      
 69 
     | 
    
         
            +
                f.name.assert == 'John'
         
     | 
| 
      
 70 
     | 
    
         
            +
                f.instance.update(:name=>'Jerry')
         
     | 
| 
      
 71 
     | 
    
         
            +
                f.name.assert == 'Jerry'
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
            ## Instance#assign
         
     | 
| 
      
 74 
     | 
    
         
            +
             
     | 
| 
      
 75 
     | 
    
         
            +
            The `#assign` method is simply an alias for `#update`.
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                f = Friend.new("John", 30, "555-1212")
         
     | 
| 
      
 78 
     | 
    
         
            +
                f.instance.assign(:name=>'Joe')
         
     | 
| 
      
 79 
     | 
    
         
            +
                f.name.assert == 'Joe'
         
     | 
| 
      
 80 
     | 
    
         
            +
             
     | 
| 
      
 81 
     | 
    
         
            +
            ## Instance#to_h
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
            We can convert the object's state, i.e. it's instance variable names and values
         
     | 
| 
      
 84 
     | 
    
         
            +
            into a Hash very easily with the `#to_h` method.
         
     | 
| 
      
 85 
     | 
    
         
            +
             
     | 
| 
      
 86 
     | 
    
         
            +
                f1 = Friend.new("John", 30, "555-1212")
         
     | 
| 
      
 87 
     | 
    
         
            +
                f1.instance.to_h.assert == {:name=>"John", :age=>30, :phone=>"555-1212"}
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
            Notice that the `@` has beenn removed from the instance variable names. If we
         
     | 
| 
      
 90 
     | 
    
         
            +
            want the `@` to stay simply pass `true` to the `#to_h` method.
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                f1 = Friend.new("John", 30, "555-1212")
         
     | 
| 
      
 93 
     | 
    
         
            +
                f1.instance.to_h(true).assert == {:@name=>"John", :@age=>30, :@phone=>"555-1212"}
         
     | 
| 
      
 94 
     | 
    
         
            +
             
     | 
| 
      
 95 
     | 
    
         
            +
            ## Instance#class
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
            To know the class of an object use the `#class` method.
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                f = Friend.new("John", 30, "555-1212")
         
     | 
| 
      
 100 
     | 
    
         
            +
                f.instance.class.assert == ::Friend
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
            Note that to get the class of Instance itself, you must use `#object_class`. 
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
            ## Instance#id
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
            To know the id of an object use the `#id` method.
         
     | 
| 
      
 107 
     | 
    
         
            +
             
     | 
| 
      
 108 
     | 
    
         
            +
                f = Friend.new("John", 30, "555-1212")
         
     | 
| 
      
 109 
     | 
    
         
            +
                f.instance.id == f.object_id
         
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
            ## Instance#of?
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
                f = Friend.new("John", 30, "555-1212")
         
     | 
| 
      
 114 
     | 
    
         
            +
                f.instance.assert.of?(::Friend)
         
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
            ## Instance#get
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
            To get the value of a specific instance variable use the `#get` or `#[]`
         
     | 
| 
      
 119 
     | 
    
         
            +
            methods.
         
     | 
| 
      
 120 
     | 
    
         
            +
             
     | 
| 
      
 121 
     | 
    
         
            +
                f = Friend.new("John", 30, "555-1212")
         
     | 
| 
      
 122 
     | 
    
         
            +
                f.instance.get(:name).assert == "John"
         
     | 
| 
      
 123 
     | 
    
         
            +
                f.instance[:name].assert == "John"
         
     | 
| 
      
 124 
     | 
    
         
            +
             
     | 
| 
      
 125 
     | 
    
         
            +
            ## Instance#set
         
     | 
| 
      
 126 
     | 
    
         
            +
             
     | 
| 
      
 127 
     | 
    
         
            +
            To set the value of a specific instance variable use the `#set` or `#[]=`
         
     | 
| 
      
 128 
     | 
    
         
            +
            methods.
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                f = Friend.new("John", 30, "555-1212")
         
     | 
| 
      
 131 
     | 
    
         
            +
             
     | 
| 
      
 132 
     | 
    
         
            +
                f.instance.set(:name, "Bill")
         
     | 
| 
      
 133 
     | 
    
         
            +
                f.name.assert == "Bill"
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
                f.instance[:name] = "Billy"
         
     | 
| 
      
 136 
     | 
    
         
            +
                f.name.assert == "Billy"
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
            ## Instance#remove
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
            To remove an instance variable from an object use the `#remove` method.
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
                f = Friend.new("John", 30, "555-1212")
         
     | 
| 
      
 143 
     | 
    
         
            +
                f.instance.remove(:name)
         
     | 
| 
      
 144 
     | 
    
         
            +
                f.instance.refute.variable_defined?(:@name)
         
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
            ## Instance#method
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
            The Instance class provides a `method` method for getting a Method object for
         
     | 
| 
      
 149 
     | 
    
         
            +
            any of the target object's methods by name.
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
                f1 = Friend.new("John", 30, "555-1212")
         
     | 
| 
      
 152 
     | 
    
         
            +
                m  = f1.instance.method(:name)
         
     | 
| 
      
 153 
     | 
    
         
            +
                m.assert.is_a?(::Method)
         
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
      
 155 
     | 
    
         
            +
            This can seem a little confusing because Ruby's `instance_method` method actually
         
     | 
| 
      
 156 
     | 
    
         
            +
            returns an `UnboundMethod` object. Unfortunately Ruby's use of the term `instance_method`
         
     | 
| 
      
 157 
     | 
    
         
            +
            is a complete misnomer. It should be something like `method_definition` instead.
         
     | 
| 
      
 158 
     | 
    
         
            +
            The actual *instance method* is the object's method.
         
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
      
 160 
     | 
    
         
            +
            ## Instance#methods
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
            We can also get a whole list of an object's methods via the `#methods` method.
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
                f = Friend.new("John", 30, "555-1212")
         
     | 
| 
      
 165 
     | 
    
         
            +
                f.instance.methods
         
     | 
| 
      
 166 
     | 
    
         
            +
                f.instance.methods(:private)
         
     | 
| 
      
 167 
     | 
    
         
            +
                f.instance.methods(:protected)
         
     | 
| 
      
 168 
     | 
    
         
            +
                f.instance.methods(:public)
         
     | 
| 
      
 169 
     | 
    
         
            +
                f.instance.methods(:public, :private)
         
     | 
| 
      
 170 
     | 
    
         
            +
             
     | 
| 
      
 171 
     | 
    
         
            +
            ## Instance#eval
         
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
      
 173 
     | 
    
         
            +
            To evaluate code in the context to the object's instance use the `#eval` method.
         
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
      
 175 
     | 
    
         
            +
                f = Friend.new("John", 30, "555-1212")
         
     | 
| 
      
 176 
     | 
    
         
            +
                f.instance.eval("@name").assert == "John"
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
      
 178 
     | 
    
         
            +
            ## Instance#exec
         
     | 
| 
      
 179 
     | 
    
         
            +
             
     | 
| 
      
 180 
     | 
    
         
            +
            Likewise the `#exec` method can also be used.
         
     | 
| 
      
 181 
     | 
    
         
            +
             
     | 
| 
      
 182 
     | 
    
         
            +
                f = Friend.new("John", 30, "555-1212")
         
     | 
| 
      
 183 
     | 
    
         
            +
                f.instance.exec{ @name }.assert == "John"
         
     | 
| 
      
 184 
     | 
    
         
            +
             
     | 
| 
      
 185 
     | 
    
         
            +
            ## Instance#send
         
     | 
| 
      
 186 
     | 
    
         
            +
             
     | 
| 
      
 187 
     | 
    
         
            +
            Sending a message to an object as if within the object itself and thus by-passing
         
     | 
| 
      
 188 
     | 
    
         
            +
            method visibility is somehting that should only be done as an act of *metaprogramming*.
         
     | 
| 
      
 189 
     | 
    
         
            +
            Hence it makes sense for it to be done via the `instance` interface.
         
     | 
| 
      
 190 
     | 
    
         
            +
             
     | 
| 
      
 191 
     | 
    
         
            +
                f = Friend.new("John", 30, "555-1212")
         
     | 
| 
      
 192 
     | 
    
         
            +
                f.instance.send(:name).assert == "John"
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
            ## Instance#delegate
         
     | 
| 
      
 195 
     | 
    
         
            +
             
     | 
| 
      
 196 
     | 
    
         
            +
            To get at the delegated object of an Instance, use the `#delegate` method.
         
     | 
| 
      
 197 
     | 
    
         
            +
             
     | 
| 
      
 198 
     | 
    
         
            +
                f = Friend.new("John", 30, "555-1212")
         
     | 
| 
      
 199 
     | 
    
         
            +
                f.instance.delegate.assert == f
         
     | 
| 
      
 200 
     | 
    
         
            +
             
     | 
| 
      
 201 
     | 
    
         
            +
             
     |