namebox 0.2.0 → 0.2.1
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.
- data/lib/namebox.rb +69 -20
- metadata +2 -2
    
        data/lib/namebox.rb
    CHANGED
    
    | @@ -13,11 +13,44 @@ | |
| 13 13 |  | 
| 14 14 | 
             
            class Namebox
         | 
| 15 15 |  | 
| 16 | 
            -
              #  | 
| 16 | 
            +
              # Currently loaded top-level modules
         | 
| 17 17 | 
             
              CORE = (Module.constants - [:Config]).
         | 
| 18 18 | 
             
                map { |c| Object.const_get(c) }.
         | 
| 19 19 | 
             
                select { |m| m.is_a? Module }.uniq
         | 
| 20 20 |  | 
| 21 | 
            +
              # Permits to call the previous (old) version of the method, by calling _old(...)
         | 
| 22 | 
            +
              module Old
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                # Check if it's already calling old, to call old and avoid recallings.
         | 
| 25 | 
            +
                def _calling_old? fullname
         | 
| 26 | 
            +
                  _calling_old.include? fullname
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                # Call the previous (old) version of the method.
         | 
| 30 | 
            +
                def _old(*args, &blk)
         | 
| 31 | 
            +
                  info = Namebox.caller_to_hash(caller[0])
         | 
| 32 | 
            +
                  method_name = info[:method]
         | 
| 33 | 
            +
                  method = self.method(method_name)
         | 
| 34 | 
            +
                  owner = method.owner
         | 
| 35 | 
            +
                  fullname = "#{owner}##{method_name}"
         | 
| 36 | 
            +
                  set_calling_old fullname
         | 
| 37 | 
            +
                  r = method.call(*args, &blk)
         | 
| 38 | 
            +
                  @_calling_old.delete(fullname)
         | 
| 39 | 
            +
                  r
         | 
| 40 | 
            +
                end
         | 
| 41 | 
            +
             | 
| 42 | 
            +
                private
         | 
| 43 | 
            +
             | 
| 44 | 
            +
                # stores info whether is calling the old version
         | 
| 45 | 
            +
                def _calling_old
         | 
| 46 | 
            +
                  @_calling_old ||= []
         | 
| 47 | 
            +
                end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                def set_calling_old fullname
         | 
| 50 | 
            +
                  _calling_old.push fullname
         | 
| 51 | 
            +
                end
         | 
| 52 | 
            +
              end
         | 
| 53 | 
            +
             | 
| 21 54 | 
             
              class << self
         | 
| 22 55 |  | 
| 23 56 | 
             
                # Wrapper to create a namebox only to protect modules when requiring.
         | 
| @@ -57,12 +90,8 @@ class Namebox | |
| 57 90 | 
             
                  c = cr[cr.index { |s| s.start_with? __FILE__ } - 1]
         | 
| 58 91 | 
             
                  raise "Unable to find a valid caller file in #{caller.inspect}" unless c
         | 
| 59 92 |  | 
| 60 | 
            -
                  #  | 
| 61 | 
            -
                   | 
| 62 | 
            -
                  raise "Unexpected caller syntax in \"#{c}\"" unless m
         | 
| 63 | 
            -
             | 
| 64 | 
            -
                  # label them
         | 
| 65 | 
            -
                  {:file => m[1], :line => m[2].to_i, :method => m[4]}
         | 
| 93 | 
            +
                  # convert into hash
         | 
| 94 | 
            +
                  caller_to_hash c
         | 
| 66 95 |  | 
| 67 96 | 
             
                end
         | 
| 68 97 |  | 
| @@ -78,6 +107,17 @@ class Namebox | |
| 78 107 | 
             
                  raise NoMethodError.new(msg)
         | 
| 79 108 | 
             
                end
         | 
| 80 109 |  | 
| 110 | 
            +
                def caller_to_hash a_caller
         | 
| 111 | 
            +
             | 
| 112 | 
            +
                  # match the info
         | 
| 113 | 
            +
                  m = a_caller.match(/^(.*?):(\d+)(:in `(.*)')?$/)
         | 
| 114 | 
            +
                  raise "Unexpected caller syntax in \"#{a_caller}\"" unless m
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                  # label them
         | 
| 117 | 
            +
                  {:file => m[1], :line => m[2].to_i, :method => m[4]}
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                end
         | 
| 120 | 
            +
             | 
| 81 121 | 
             
              end
         | 
| 82 122 |  | 
| 83 123 | 
             
              # +modules_to_protect+ must be the classes themselves, e.g., String, Symbol,
         | 
| @@ -127,10 +167,10 @@ class Namebox | |
| 127 167 | 
             
                  # avoid redundancy
         | 
| 128 168 | 
             
                  @modules.uniq!
         | 
| 129 169 |  | 
| 130 | 
            -
                  # include all ancestors for modules and  | 
| 170 | 
            +
                  # include all ancestors for modules and singleton classes of classes
         | 
| 131 171 | 
             
                  modules.each do |m|
         | 
| 132 172 | 
             
                    @modules |= m.ancestors
         | 
| 133 | 
            -
                    @modules |=  | 
| 173 | 
            +
                    @modules |= m.singleton_class.ancestors if m.is_a? Class
         | 
| 134 174 | 
             
                  end
         | 
| 135 175 | 
             
                end
         | 
| 136 176 |  | 
| @@ -144,12 +184,12 @@ class Namebox | |
| 144 184 | 
             
                # select classes to protect against included modules
         | 
| 145 185 | 
             
                @classes = @modules.select { |m| m.is_a? Class }
         | 
| 146 186 |  | 
| 147 | 
            -
                # get  | 
| 148 | 
            -
                 | 
| 187 | 
            +
                # get singleton_classes
         | 
| 188 | 
            +
                singleton_classes = @classes.map { |c| c.singleton_class }
         | 
| 149 189 |  | 
| 150 | 
            -
                # include  | 
| 151 | 
            -
                @classes |=  | 
| 152 | 
            -
                @modules |=  | 
| 190 | 
            +
                # include singleton_classes into @classes and @modules
         | 
| 191 | 
            +
                @classes |= singleton_classes
         | 
| 192 | 
            +
                @modules |= singleton_classes
         | 
| 153 193 |  | 
| 154 194 | 
             
                # save preexisting methods and included modules
         | 
| 155 195 | 
             
                inc_mods_before = get_included_modules
         | 
| @@ -219,10 +259,10 @@ class Namebox | |
| 219 259 | 
             
                    klass.send :define_method, method_name do |*args, &blk|
         | 
| 220 260 |  | 
| 221 261 | 
             
                      # check namebox visibility
         | 
| 222 | 
            -
                      if this_nb.open?
         | 
| 262 | 
            +
                      if this_nb.open? && !_calling_old?(fullname)
         | 
| 223 263 |  | 
| 224 264 | 
             
                        # namebox method; bind instance method to self.
         | 
| 225 | 
            -
                        new_method.bind(self).call(*args, &blk)
         | 
| 265 | 
            +
                        r = new_method.bind(self).call(*args, &blk)
         | 
| 226 266 |  | 
| 227 267 | 
             
                      else
         | 
| 228 268 |  | 
| @@ -234,7 +274,12 @@ class Namebox | |
| 234 274 | 
             
                        end
         | 
| 235 275 |  | 
| 236 276 | 
             
                      end
         | 
| 277 | 
            +
             | 
| 237 278 | 
             
                    end
         | 
| 279 | 
            +
             | 
| 280 | 
            +
                    # permits to call the old methods
         | 
| 281 | 
            +
                    klass.send :include, Namebox::Old
         | 
| 282 | 
            +
             | 
| 238 283 | 
             
                  end
         | 
| 239 284 | 
             
                end
         | 
| 240 285 | 
             
              end
         | 
| @@ -378,7 +423,7 @@ class Namebox | |
| 378 423 |  | 
| 379 424 | 
             
                  # Give a name to protector module; useful when using Method#owner.
         | 
| 380 425 | 
             
                  #
         | 
| 381 | 
            -
                   | 
| 426 | 
            +
                  protector.singleton_class.send(:define_method, :to_s) do
         | 
| 382 427 | 
             
                    "Protector:#{new_module}"
         | 
| 383 428 | 
             
                  end
         | 
| 384 429 |  | 
| @@ -389,10 +434,11 @@ class Namebox | |
| 389 434 | 
             
                    protector.send :define_method, method_name do |*args, &blk|
         | 
| 390 435 |  | 
| 391 436 | 
             
                      # check namebox visibility
         | 
| 392 | 
            -
                       | 
| 437 | 
            +
                      fullname = "#{protector}##{method_name}"
         | 
| 438 | 
            +
                      if this_nb.open? && !_calling_old?(fullname)
         | 
| 393 439 |  | 
| 394 440 | 
             
                        # namebox method; bind instance method to self.
         | 
| 395 | 
            -
                        new_method.bind(self).call(*args, &blk)
         | 
| 441 | 
            +
                        r = new_method.bind(self).call(*args, &blk)
         | 
| 396 442 |  | 
| 397 443 | 
             
                      else
         | 
| 398 444 |  | 
| @@ -409,7 +455,10 @@ class Namebox | |
| 409 455 |  | 
| 410 456 | 
             
                  end
         | 
| 411 457 |  | 
| 412 | 
            -
                  #  | 
| 458 | 
            +
                  # permits to call the old methods
         | 
| 459 | 
            +
                  new_module.send :include, Namebox::Old
         | 
| 460 | 
            +
             | 
| 461 | 
            +
                  # include super_tunnel in new_module (must be included after Old)
         | 
| 413 462 | 
             
                  new_module.send :include, super_tunnel
         | 
| 414 463 |  | 
| 415 464 | 
             
                  @protector_modules[new_module] = protector
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: namebox
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.2. | 
| 4 | 
            +
              version: 0.2.1
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| @@ -9,7 +9,7 @@ authors: | |
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2013-01- | 
| 12 | 
            +
            date: 2013-01-27 00:00:00.000000000 Z
         | 
| 13 13 | 
             
            dependencies: []
         | 
| 14 14 | 
             
            description: ! 'Create namespace boxes to protect the core classes'' methods from
         | 
| 15 15 | 
             
              changes, like refinements.
         |