Skip to content
This repository

RouteSet: decomplecting a way to handle positional args #5957

Merged
merged 1 commit into from about 2 years ago

3 participants

Bogdan Gusiev Carlos Antonio da Silva José Valim
Bogdan Gusiev

Currently positional arguments are handle with a nasty hack: bypassing them though options hash.
This make code wider and harder to understand.

This patch merges it all together and removes options[:_positional_args] and options[:_positional_keys] hack.

Ensure no performance degrade:

https://gist.github.com/2479082


$ diffbench perf.rb
Running benchmark with current working tree
Stashing changes
Running benchmark with clean working tree
Applying stashed changes back

                    user     system      total        real
----------------------------------Url helper module builder
After patch:    0.410000   0.000000   0.410000 (  0.409276)
Before patch:   0.410000   0.000000   0.410000 (  0.413838)

--------------------------------------simple URL generation
After patch:    0.010000   0.000000   0.010000 (  0.005349)
Before patch:   0.000000   0.000000   0.000000 (  0.005511)

--------------------URL generation with optional parameters
After patch:    0.090000   0.000000   0.090000 (  0.091728)
Before patch:   0.100000   0.000000   0.100000 (  0.092634)
José Valim josevalim merged commit afcae34 into from
Carlos Antonio da Silva carlosantoniodasilva commented on the diff
actionpack/lib/action_dispatch/routing/route_set.rb
@@ -96,7 +96,24 @@ class NamedRouteCollection #:nodoc:
96 96 def initialize
97 97 @routes = {}
98 98 @helpers = []
99   - @module = Module.new
  99 + @module = Module.new do
  100 + protected
  101 + def handle_positional_args(args, options, route)
  102 + inner_options = args.extract_options!
  103 + result = options.dup
  104 +
  105 + if args.any?
  106 + keys = route.segment_keys
  107 + if args.size < keys.size - 1 # take format into account
  108 + keys -= self.url_options.keys if self.respond_to?(:url_options)
  109 + keys -= options.keys
  110 + end
  111 + result.merge!(Hash[args.zip(keys).map { |v, k| [k, v] }])
6

Can this be handle by Hash#invert?

# before
Hash[args.zip(keys).map { |v, k| [k, v] }]
# after
Hash[args.zip(keys)].invert

Wdyt?

Bogdan Gusiev
bogdan added a note

I was just copy pasting that line,
You can check it on your side to be sure.

Yeah I see that they are the same lines. I'll check later, thanks.

José Valim Owner
josevalim added a note

Couldn't we simply do? keys.zip(args)

Done #5959

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 1 unique commit by 1 author.

Apr 24, 2012
Bogdan Gusiev bogdan RouteSet: decomplecting a way to handle positional args 65ec1e9
This page is out of date. Refresh to see the latest.

Showing 1 changed file with 20 additions and 26 deletions. Show diff stats Hide diff stats

  1. +20 26 actionpack/lib/action_dispatch/routing/route_set.rb
46 actionpack/lib/action_dispatch/routing/route_set.rb
@@ -96,7 +96,24 @@ class NamedRouteCollection #:nodoc:
96 96 def initialize
97 97 @routes = {}
98 98 @helpers = []
99   - @module = Module.new
  99 + @module = Module.new do
  100 + protected
  101 + def handle_positional_args(args, options, route)
  102 + inner_options = args.extract_options!
  103 + result = options.dup
  104 +
  105 + if args.any?
  106 + keys = route.segment_keys
  107 + if args.size < keys.size - 1 # take format into account
  108 + keys -= self.url_options.keys if self.respond_to?(:url_options)
  109 + keys -= options.keys
  110 + end
  111 + result.merge!(Hash[args.zip(keys).map { |v, k| [k, v] }])
  112 + end
  113 +
  114 + result.merge!(inner_options)
  115 + end
  116 + end
100 117 end
101 118
102 119 def helper_names
@@ -163,20 +180,9 @@ def define_hash_access(route, name, options)
163 180 selector = hash_access_name(name, options[:only_path])
164 181
165 182 @module.module_eval do
166   - remove_possible_method selector
167   -
168   - define_method(selector) do |*args|
169   - inner_options = args.extract_options!
170   - result = options.dup
171   -
172   - if args.any?
173   - result[:_positional_args] = args
174   - result[:_positional_keys] = route.segment_keys
175   - end
176   -
177   - result.merge(inner_options)
  183 + redefine_method(selector) do |*args|
  184 + self.handle_positional_args(args, options, route)
178 185 end
179   -
180 186 protected selector
181 187 end
182 188 helpers << selector
@@ -617,8 +623,6 @@ def _generate_prefix(options = {})
617 623 def url_for(options)
618 624 options = default_url_options.merge(options || {})
619 625
620   - handle_positional_args(options)
621   -
622 626 user, password = extract_authentication(options)
623 627 path_segments = options.delete(:_path_segments)
624 628 script_name = options.delete(:script_name).presence || _generate_prefix(options)
@@ -688,16 +692,6 @@ def extract_authentication(options)
688 692 end
689 693 end
690 694
691   - def handle_positional_args(options)
692   - return unless args = options.delete(:_positional_args)
693   -
694   - keys = options.delete(:_positional_keys)
695   - keys -= options.keys if args.size < keys.size - 1 # take format into account
696   -
697   - # Tell url_for to skip default_url_options
698   - options.merge!(Hash[args.zip(keys).map { |v, k| [k, v] }])
699   - end
700   -
701 695 end
702 696 end
703 697 end

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.