sass 3.3.0.alpha.256 → 3.3.0.alpha.353

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/REVISION +1 -1
  2. data/Rakefile +21 -1
  3. data/VERSION +1 -1
  4. data/VERSION_DATE +1 -1
  5. data/lib/sass.rb +6 -3
  6. data/lib/sass/cache_stores/base.rb +1 -1
  7. data/lib/sass/cache_stores/chain.rb +2 -1
  8. data/lib/sass/cache_stores/filesystem.rb +2 -6
  9. data/lib/sass/cache_stores/memory.rb +1 -1
  10. data/lib/sass/cache_stores/null.rb +2 -2
  11. data/lib/sass/callbacks.rb +1 -0
  12. data/lib/sass/css.rb +6 -6
  13. data/lib/sass/engine.rb +60 -34
  14. data/lib/sass/environment.rb +3 -1
  15. data/lib/sass/error.rb +5 -5
  16. data/lib/sass/exec.rb +52 -25
  17. data/lib/sass/features.rb +0 -2
  18. data/lib/sass/importers/deprecated_path.rb +1 -1
  19. data/lib/sass/importers/filesystem.rb +8 -6
  20. data/lib/sass/logger/base.rb +3 -3
  21. data/lib/sass/logger/log_level.rb +4 -6
  22. data/lib/sass/media.rb +2 -2
  23. data/lib/sass/plugin.rb +4 -2
  24. data/lib/sass/plugin/compiler.rb +28 -15
  25. data/lib/sass/plugin/configuration.rb +15 -7
  26. data/lib/sass/plugin/merb.rb +1 -1
  27. data/lib/sass/plugin/staleness_checker.rb +24 -8
  28. data/lib/sass/repl.rb +3 -3
  29. data/lib/sass/script.rb +2 -1
  30. data/lib/sass/script/css_lexer.rb +8 -3
  31. data/lib/sass/script/css_parser.rb +6 -2
  32. data/lib/sass/script/functions.rb +164 -109
  33. data/lib/sass/script/lexer.rb +30 -20
  34. data/lib/sass/script/parser.rb +66 -37
  35. data/lib/sass/script/tree/funcall.rb +23 -14
  36. data/lib/sass/script/tree/interpolation.rb +5 -1
  37. data/lib/sass/script/tree/list_literal.rb +5 -4
  38. data/lib/sass/script/tree/map_literal.rb +1 -1
  39. data/lib/sass/script/tree/node.rb +2 -2
  40. data/lib/sass/script/tree/operation.rb +2 -1
  41. data/lib/sass/script/tree/selector.rb +3 -2
  42. data/lib/sass/script/tree/string_interpolation.rb +2 -1
  43. data/lib/sass/script/tree/variable.rb +4 -3
  44. data/lib/sass/script/value/base.rb +12 -14
  45. data/lib/sass/script/value/color.rb +35 -16
  46. data/lib/sass/script/value/helpers.rb +146 -0
  47. data/lib/sass/script/value/list.rb +24 -5
  48. data/lib/sass/script/value/map.rb +1 -1
  49. data/lib/sass/script/value/null.rb +13 -3
  50. data/lib/sass/script/value/number.rb +44 -35
  51. data/lib/sass/script/value/string.rb +2 -2
  52. data/lib/sass/scss/css_parser.rb +2 -1
  53. data/lib/sass/scss/parser.rb +143 -93
  54. data/lib/sass/scss/rx.rb +4 -4
  55. data/lib/sass/scss/script_lexer.rb +1 -0
  56. data/lib/sass/scss/script_parser.rb +1 -0
  57. data/lib/sass/scss/static_parser.rb +5 -5
  58. data/lib/sass/selector.rb +5 -2
  59. data/lib/sass/selector/abstract_sequence.rb +1 -1
  60. data/lib/sass/selector/comma_sequence.rb +16 -14
  61. data/lib/sass/selector/sequence.rb +38 -24
  62. data/lib/sass/selector/simple.rb +4 -4
  63. data/lib/sass/selector/simple_sequence.rb +21 -11
  64. data/lib/sass/source/map.rb +7 -2
  65. data/lib/sass/source/range.rb +1 -1
  66. data/lib/sass/supports.rb +3 -3
  67. data/lib/sass/tree/debug_node.rb +1 -1
  68. data/lib/sass/tree/function_node.rb +2 -1
  69. data/lib/sass/tree/if_node.rb +1 -1
  70. data/lib/sass/tree/import_node.rb +3 -4
  71. data/lib/sass/tree/prop_node.rb +4 -2
  72. data/lib/sass/tree/rule_node.rb +5 -2
  73. data/lib/sass/tree/visitors/base.rb +6 -6
  74. data/lib/sass/tree/visitors/check_nesting.rb +12 -9
  75. data/lib/sass/tree/visitors/convert.rb +34 -28
  76. data/lib/sass/tree/visitors/cssize.rb +4 -3
  77. data/lib/sass/tree/visitors/deep_copy.rb +1 -0
  78. data/lib/sass/tree/visitors/perform.rb +31 -16
  79. data/lib/sass/tree/visitors/to_css.rb +34 -16
  80. data/lib/sass/util.rb +88 -37
  81. data/lib/sass/util/multibyte_string_scanner.rb +2 -0
  82. data/lib/sass/util/ordered_hash.rb +20 -18
  83. data/lib/sass/util/subset_map.rb +3 -2
  84. data/lib/sass/util/test.rb +0 -1
  85. data/lib/sass/version.rb +9 -5
  86. data/test/rubocop_extensions.rb +70 -0
  87. data/test/sass/functions_test.rb +20 -1
  88. data/test/sass/importer_test.rb +2 -1
  89. data/test/sass/script_test.rb +4 -0
  90. data/test/sass/source_map_test.rb +1 -1
  91. data/test/sass/util_test.rb +49 -0
  92. data/test/sass/value_helpers_test.rb +181 -0
  93. metadata +13 -9
@@ -63,7 +63,7 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
63
63
  @offset -= chars
64
64
  end
65
65
  end
66
-
66
+
67
67
  # Avoid allocating lots of new strings for `#output`. This is important
68
68
  # because `#output` is called all the time.
69
69
  NEWLINE = "\n"
@@ -157,11 +157,17 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
157
157
  spaces = (' ' * [@tabs - node.resolved_value[/^ */].size, 0].max)
158
158
 
159
159
  content = node.resolved_value.gsub(/^/, spaces)
160
- content.gsub!(%r{^(\s*)//(.*)$}) {|md| "#{$1}/*#{$2} */"} if node.type == :silent
161
- content.gsub!(/\n +(\* *(?!\/))?/, ' ') if (node.style == :compact || node.style == :compressed) && node.type != :loud
160
+ if node.type == :silent
161
+ content.gsub!(%r{^(\s*)//(.*)$}) {|md| "#{$1}/*#{$2} */"}
162
+ end
163
+ if (node.style == :compact || node.style == :compressed) && node.type != :loud
164
+ content.gsub!(/\n +(\* *(?!\/))?/, ' ')
165
+ end
162
166
  for_node(node) {output(content)}
163
167
  end
164
168
 
169
+ # @comment
170
+ # rubocop:disable MethodLength
165
171
  def visit_directive(node)
166
172
  was_in_directive = @in_directive
167
173
  tab_str = ' ' * @tabs
@@ -224,6 +230,8 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
224
230
  ensure
225
231
  @in_directive = was_in_directive
226
232
  end
233
+ # @comment
234
+ # rubocop:enable MethodLength
227
235
 
228
236
  def visit_media(node)
229
237
  with_tabs(@tabs + node.tabs) {visit_directive(node)}
@@ -244,7 +252,7 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
244
252
  output(tab_str)
245
253
  for_node(node, :name) {output(node.resolved_name)}
246
254
  if node.style == :compressed
247
- output(":");
255
+ output(":")
248
256
  for_node(node, :value) {output(node.resolved_value)}
249
257
  else
250
258
  output(": ")
@@ -253,17 +261,23 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
253
261
  end
254
262
  end
255
263
 
264
+ # @comment
265
+ # rubocop:disable MethodLength
256
266
  def visit_rule(node)
257
267
  with_tabs(@tabs + node.tabs) do
258
268
  rule_separator = node.style == :compressed ? ',' : ', '
259
269
  line_separator =
260
270
  case node.style
261
- when :nested, :expanded; "\n"
262
- when :compressed; ""
263
- else; " "
271
+ when :nested, :expanded; "\n"
272
+ when :compressed; ""
273
+ else; " "
264
274
  end
265
275
  rule_indent = ' ' * @tabs
266
- per_rule_indent, total_indent = [:nested, :expanded].include?(node.style) ? [rule_indent, ''] : ['', rule_indent]
276
+ per_rule_indent, total_indent = if [:nested, :expanded].include?(node.style)
277
+ [rule_indent, '']
278
+ else
279
+ ['', rule_indent]
280
+ end
267
281
 
268
282
  joined_rules = node.resolved_rules.members.map do |seq|
269
283
  next if seq.has_placeholder?
@@ -293,13 +307,13 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
293
307
 
294
308
  if node.filename
295
309
  relative_filename = if node.options[:css_filename]
296
- begin
297
- Pathname.new(node.filename).relative_path_from(
298
- Pathname.new(File.dirname(node.options[:css_filename]))).to_s
299
- rescue ArgumentError
300
- nil
301
- end
302
- end
310
+ begin
311
+ Pathname.new(node.filename).relative_path_from(
312
+ Pathname.new(File.dirname(node.options[:css_filename]))).to_s
313
+ rescue ArgumentError
314
+ nil
315
+ end
316
+ end
303
317
  relative_filename ||= node.filename
304
318
  output(", #{relative_filename}")
305
319
  end
@@ -335,6 +349,8 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
335
349
  output("}" + trailer)
336
350
  end
337
351
  end
352
+ # @comment
353
+ # rubocop:enable MethodLength
338
354
 
339
355
  private
340
356
 
@@ -355,7 +371,9 @@ class Sass::Tree::Visitors::ToCss < Sass::Tree::Visitors::Base
355
371
  rule << prop
356
372
  node << rule
357
373
  end
358
- node.options = options.merge(:debug_info => false, :line_comments => false, :style => :compressed)
374
+ node.options = options.merge(:debug_info => false,
375
+ :line_comments => false,
376
+ :style => :compressed)
359
377
  node
360
378
  end
361
379
  end
@@ -4,6 +4,7 @@ require 'enumerator'
4
4
  require 'stringio'
5
5
  require 'rbconfig'
6
6
  require 'uri'
7
+ require 'thread'
7
8
 
8
9
  require 'sass/root'
9
10
  require 'sass/util/subset_map'
@@ -57,7 +58,7 @@ module Sass
57
58
  end
58
59
 
59
60
  return Hash[pairs_or_hash] unless ruby1_8?
60
- return OrderedHash[*flatten(pairs_or_hash, 1)]
61
+ OrderedHash[*flatten(pairs_or_hash, 1)]
61
62
  end
62
63
 
63
64
  # Converts an array of `[key, value]` pairs to a hash.
@@ -195,8 +196,8 @@ module Sass
195
196
  res = ary.dup
196
197
  i = 0
197
198
  while i < res.size
198
- if res[i...i+from.size] == from
199
- res[i...i+from.size] = to
199
+ if res[i...i + from.size] == from
200
+ res[i...i + from.size] = to
200
201
  end
201
202
  i += 1
202
203
  end
@@ -247,7 +248,7 @@ module Sass
247
248
  x = [nil, *x]
248
249
  y = [nil, *y]
249
250
  block ||= proc {|a, b| a == b && a}
250
- lcs_backtrace(lcs_table(x, y, &block), x, y, x.size-1, y.size-1, &block)
251
+ lcs_backtrace(lcs_table(x, y, &block), x, y, x.size - 1, y.size - 1, &block)
251
252
  end
252
253
 
253
254
  # Converts a Hash to an Array. This is usually identical to `Hash#to_a`,
@@ -261,7 +262,7 @@ module Sass
261
262
  # @return [Array]
262
263
  def hash_to_a(hash)
263
264
  return hash.to_a unless ruby1_8? || defined?(Test::Unit)
264
- return hash.sort_by {|k, v| k}
265
+ hash.sort_by {|k, v| k}
265
266
  end
266
267
 
267
268
  # Performs the equivalent of `enum.group_by.to_a`, but with a guaranteed
@@ -275,13 +276,14 @@ module Sass
275
276
  return enum.group_by(&block).to_a unless ruby1_8?
276
277
  order = {}
277
278
  arr = []
278
- enum.group_by do |e|
279
+ groups = enum.group_by do |e|
279
280
  res = block[e]
280
281
  unless order.include?(res)
281
282
  order[res] = order.size
282
283
  end
283
284
  res
284
- end.each do |key, vals|
285
+ end
286
+ groups.each do |key, vals|
285
287
  arr[order[key]] = [key, vals]
286
288
  end
287
289
  arr
@@ -311,7 +313,7 @@ module Sass
311
313
  # JRuby (as of 1.7.2) doesn't have an error_char field on
312
314
  # Encoding::UndefinedConversionError.
313
315
  return e.error_char.dump unless jruby?
314
- e.message[/^"[^"]+"/] #"
316
+ e.message[/^"[^"]+"/] # "
315
317
  end
316
318
 
317
319
  # Asserts that `value` falls within `range` (inclusive), leaving
@@ -323,7 +325,7 @@ module Sass
323
325
  # @param unit [String] The unit of the value. Used in error reporting.
324
326
  # @return [Numeric] `value` adjusted to fall within range, if it
325
327
  # was outside by a floating-point margin.
326
- def check_range(name, range, value, unit='')
328
+ def check_range(name, range, value, unit = '')
327
329
  grace = (-0.00001..0.00001)
328
330
  str = value.to_s
329
331
  value = value.value if value.is_a?(Sass::Script::Value::Number)
@@ -354,7 +356,8 @@ module Sass
354
356
  # Returns information about the caller of the previous method.
355
357
  #
356
358
  # @param entry [String] An entry in the `#caller` list, or a similarly formatted string
357
- # @return [[String, Fixnum, (String, nil)]] An array containing the filename, line, and method name of the caller.
359
+ # @return [[String, Fixnum, (String, nil)]]
360
+ # An array containing the filename, line, and method name of the caller.
358
361
  # The method name may be nil
359
362
  def caller_info(entry = nil)
360
363
  # JRuby evaluates `caller` incorrectly when it's in an actual default argument.
@@ -422,7 +425,6 @@ module Sass
422
425
  $stderr = the_real_stderr
423
426
  end
424
427
 
425
- @@silence_warnings = false
426
428
  # Silences all Sass warnings within a block.
427
429
  #
428
430
  # @yield A block in which no Sass warnings will be printed
@@ -454,7 +456,7 @@ module Sass
454
456
  raise "ERROR: Rails.root is nil!"
455
457
  end
456
458
  return RAILS_ROOT.to_s if defined?(RAILS_ROOT)
457
- return nil
459
+ nil
458
460
  end
459
461
 
460
462
  # Returns the environment of the Rails application,
@@ -465,7 +467,7 @@ module Sass
465
467
  def rails_env
466
468
  return ::Rails.env.to_s if defined?(::Rails.env)
467
469
  return RAILS_ENV.to_s if defined?(RAILS_ENV)
468
- return nil
470
+ nil
469
471
  end
470
472
 
471
473
  # Returns whether this environment is using ActionPack
@@ -501,7 +503,7 @@ module Sass
501
503
  # or `ActionView::Template::Error`.
502
504
  def av_template_class(name)
503
505
  return ActionView.const_get("Template#{name}") if ActionView.const_defined?("Template#{name}")
504
- return ActionView::Template.const_get(name.to_s)
506
+ ActionView::Template.const_get(name.to_s)
505
507
  end
506
508
 
507
509
  ## Cross-OS Compatibility
@@ -534,11 +536,16 @@ module Sass
534
536
  RUBY_PLATFORM =~ /java/
535
537
  end
536
538
 
539
+ # @see #jruby_version-class_method
540
+ def jruby_version
541
+ Sass::Util.jruby_version
542
+ end
543
+
537
544
  # Returns an array of ints representing the JRuby version number.
538
545
  #
539
546
  # @return [Array<Fixnum>]
540
- def jruby_version
541
- $jruby_version ||= ::JRUBY_VERSION.split(".").map {|s| s.to_i}
547
+ def self.jruby_version
548
+ @jruby_version ||= ::JRUBY_VERSION.split(".").map {|s| s.to_i}
542
549
  end
543
550
 
544
551
  # Like `Dir.glob`, but works with backslash-separated paths on Windows.
@@ -636,7 +643,7 @@ Invalid #{encoding.name} character #{undefined_conversion_error_char(e)}
636
643
  MSG
637
644
  end
638
645
  end
639
- return str
646
+ str
640
647
  end
641
648
 
642
649
  # Like {\#check\_encoding}, but also checks for a `@charset` declaration
@@ -669,7 +676,7 @@ MSG
669
676
  charset, bom = $1, $2
670
677
  if charset
671
678
  charset = charset.force_encoding(encoding).encode("UTF-8")
672
- if endianness = encoding[/[BL]E$/]
679
+ if (endianness = encoding[/[BL]E$/])
673
680
  begin
674
681
  Encoding.find(charset + endianness)
675
682
  charset << endianness
@@ -816,8 +823,9 @@ MSG
816
823
  set1.to_a.uniq.sort_by {|e| e.hash}.eql?(set2.to_a.uniq.sort_by {|e| e.hash})
817
824
  end
818
825
 
819
- # Like `Object#inspect`, but preserves non-ASCII characters rather than escaping them under Ruby 1.9.2.
820
- # This is necessary so that the precompiled Haml template can be `#encode`d into `@options[:encoding]`
826
+ # Like `Object#inspect`, but preserves non-ASCII characters rather than
827
+ # escaping them under Ruby 1.9.2. This is necessary so that the
828
+ # precompiled Haml template can be `#encode`d into `@options[:encoding]`
821
829
  # before being evaluated.
822
830
  #
823
831
  # @param obj {Object}
@@ -843,11 +851,12 @@ MSG
843
851
  # @return [(String, Array)] The resulting string, and an array of extracted values.
844
852
  def extract_values(arr)
845
853
  values = []
846
- return arr.map do |e|
854
+ mapped = arr.map do |e|
847
855
  next e.gsub('{', '{{') if e.is_a?(String)
848
856
  values << e
849
857
  next "{#{values.count - 1}}"
850
- end.join, values
858
+ end
859
+ return mapped.join, values
851
860
  end
852
861
 
853
862
  # Undoes \{#extract\_values} by transforming a string with escape sequences
@@ -962,7 +971,7 @@ MSG
962
971
  value <<= 1
963
972
  end
964
973
 
965
- result = String.new
974
+ result = ''
966
975
  begin
967
976
  digit = value & VLQ_BASE_MASK
968
977
  value >>= VLQ_BASE_SHIFT
@@ -974,6 +983,21 @@ MSG
974
983
  result
975
984
  end
976
985
 
986
+ # This is a hack around the fact that you can't instantiate a URI parser on
987
+ # 1.8, so we have to have this hacky stuff to work around it. When 1.8
988
+ # support is dropped, we can remove this method.
989
+ #
990
+ # @private
991
+ URI_ESCAPE = URI.const_defined?("DEFAULT_PARSER") ? URI::DEFAULT_PARSER : URI
992
+
993
+ # URI-escape `string`.
994
+ #
995
+ # @param string [String]
996
+ # @return [String]
997
+ def escape_uri(string)
998
+ URI_ESCAPE.escape string
999
+ end
1000
+
977
1001
  ## Static Method Stuff
978
1002
 
979
1003
  # The context in which the ERB for \{#def\_static\_method} will be run.
@@ -993,20 +1017,43 @@ MSG
993
1017
  end
994
1018
  end
995
1019
 
996
-
997
- URI_ESCAPE = URI.const_defined?(:DEFAULT_PARSER) ?
998
- URI::DEFAULT_PARSER :
999
- URI
1000
-
1001
- def escape_uri(uri)
1002
- URI_ESCAPE.escape uri
1020
+ # @private
1021
+ ATOMIC_WRITE_MUTEX = Mutex.new
1022
+
1023
+ # This creates a temp file and yields it for writing. When the
1024
+ # write is complete, the file is moved into the desired location.
1025
+ # The atomicity of this operation is provided by the filesystem's
1026
+ # rename operation.
1027
+ #
1028
+ # @param filename [String] The file to write to.
1029
+ # @yieldparam tmpfile [Tempfile] The temp file that can be written to.
1030
+ # @return The value returned by the block.
1031
+ def atomic_create_and_write_file(filename)
1032
+ require 'tempfile'
1033
+ tmpfile = Tempfile.new(File.basename(filename), File.dirname(filename))
1034
+ tmpfile.binmode if tmpfile.respond_to?(:binmode)
1035
+ result = yield tmpfile
1036
+ tmpfile.close
1037
+ ATOMIC_WRITE_MUTEX.synchronize do
1038
+ File.rename tmpfile.path, filename
1039
+ end
1040
+ result
1041
+ ensure
1042
+ # close and remove the tempfile if it still exists,
1043
+ # presumably due to an error during write
1044
+ tmpfile.close if tmpfile
1045
+ tmpfile.unlink if tmpfile
1003
1046
  end
1004
1047
 
1005
1048
  private
1006
1049
 
1050
+ # rubocop:disable LineLength
1051
+
1052
+
1007
1053
  # Calculates the memoization table for the Least Common Subsequence algorithm.
1008
1054
  # Algorithm from [Wikipedia](http://en.wikipedia.org/wiki/Longest_common_subsequence_problem#Computing_the_length_of_the_LCS)
1009
1055
  def lcs_table(x, y)
1056
+ # rubocop:enable LineLength
1010
1057
  c = Array.new(x.size) {[]}
1011
1058
  x.size.times {|i| c[i][0] = 0}
1012
1059
  y.size.times {|j| c[0][j] = 0}
@@ -1014,25 +1061,29 @@ MSG
1014
1061
  (1...y.size).each do |j|
1015
1062
  c[i][j] =
1016
1063
  if yield x[i], y[j]
1017
- c[i-1][j-1] + 1
1064
+ c[i - 1][j - 1] + 1
1018
1065
  else
1019
- [c[i][j-1], c[i-1][j]].max
1066
+ [c[i][j - 1], c[i - 1][j]].max
1020
1067
  end
1021
1068
  end
1022
1069
  end
1023
- return c
1070
+ c
1024
1071
  end
1025
1072
 
1073
+ # rubocop:disable ParameterLists, LineLength
1074
+
1075
+
1026
1076
  # Computes a single longest common subsequence for arrays x and y.
1027
1077
  # Algorithm from [Wikipedia](http://en.wikipedia.org/wiki/Longest_common_subsequence_problem#Reading_out_an_LCS)
1028
1078
  def lcs_backtrace(c, x, y, i, j, &block)
1079
+ # rubocop:enable ParameterList, LineLengths
1029
1080
  return [] if i == 0 || j == 0
1030
- if v = yield(x[i], y[j])
1031
- return lcs_backtrace(c, x, y, i-1, j-1, &block) << v
1081
+ if (v = yield(x[i], y[j]))
1082
+ return lcs_backtrace(c, x, y, i - 1, j - 1, &block) << v
1032
1083
  end
1033
1084
 
1034
- return lcs_backtrace(c, x, y, i, j-1, &block) if c[i][j-1] > c[i-1][j]
1035
- return lcs_backtrace(c, x, y, i-1, j, &block)
1085
+ return lcs_backtrace(c, x, y, i, j - 1, &block) if c[i][j - 1] > c[i - 1][j]
1086
+ lcs_backtrace(c, x, y, i - 1, j, &block)
1036
1087
  end
1037
1088
  end
1038
1089
  end
@@ -1,7 +1,9 @@
1
1
  require 'strscan'
2
2
 
3
3
  if Sass::Util.ruby1_8?
4
+ # rubocop:disable ConstantName
4
5
  Sass::Util::MultibyteStringScanner = StringScanner
6
+ # rubocop:enable ConstantName
5
7
  else
6
8
  if Sass::Util.rbx?
7
9
  # Rubinius's StringScanner class implements some of its methods in terms of
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2005-2013 David Heinemeier Hansson
2
- #
2
+ #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining
4
4
  # a copy of this software and associated documentation files (the
5
5
  # "Software"), to deal in the Software without restriction, including
@@ -7,10 +7,10 @@
7
7
  # distribute, sublicense, and/or sell copies of the Software, and to
8
8
  # permit persons to whom the Software is furnished to do so, subject to
9
9
  # the following conditions:
10
- #
10
+ #
11
11
  # The above copyright notice and this permission notice shall be
12
12
  # included in all copies or substantial portions of the Software.
13
- #
13
+ #
14
14
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
15
  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
16
  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -39,21 +39,21 @@ class OrderedHash < ::Hash
39
39
  def self.[](*args)
40
40
  ordered_hash = new
41
41
 
42
- if (args.length == 1 && args.first.is_a?(Array))
42
+ if args.length == 1 && args.first.is_a?(Array)
43
43
  args.first.each do |key_value_pair|
44
- next unless (key_value_pair.is_a?(Array))
44
+ next unless key_value_pair.is_a?(Array)
45
45
  ordered_hash[key_value_pair[0]] = key_value_pair[1]
46
46
  end
47
47
 
48
48
  return ordered_hash
49
49
  end
50
50
 
51
- unless (args.size % 2 == 0)
51
+ unless args.size.even?
52
52
  raise ArgumentError.new("odd number of arguments for Hash")
53
53
  end
54
54
 
55
55
  args.each_with_index do |val, ind|
56
- next if (ind % 2 != 0)
56
+ next if ind.odd?
57
57
  ordered_hash[val] = args[ind + 1]
58
58
  end
59
59
 
@@ -100,7 +100,7 @@ class OrderedHash < ::Hash
100
100
  end
101
101
 
102
102
  def values
103
- @keys.collect { |key| self[key] }
103
+ @keys.map {|key| self[key]}
104
104
  end
105
105
 
106
106
  def to_hash
@@ -108,18 +108,18 @@ class OrderedHash < ::Hash
108
108
  end
109
109
 
110
110
  def to_a
111
- @keys.map { |key| [ key, self[key] ] }
111
+ @keys.map {|key| [key, self[key]]}
112
112
  end
113
113
 
114
114
  def each_key
115
115
  return to_enum(:each_key) unless block_given?
116
- @keys.each { |key| yield key }
116
+ @keys.each {|key| yield key}
117
117
  self
118
118
  end
119
119
 
120
120
  def each_value
121
121
  return to_enum(:each_value) unless block_given?
122
- @keys.each { |key| yield self[key]}
122
+ @keys.each {|key| yield self[key]}
123
123
  self
124
124
  end
125
125
 
@@ -151,9 +151,9 @@ class OrderedHash < ::Hash
151
151
 
152
152
  def merge!(other_hash)
153
153
  if block_given?
154
- other_hash.each { |k, v| self[k] = key?(k) ? yield(k, self[k], v) : v }
154
+ other_hash.each {|k, v| self[k] = key?(k) ? yield(k, self[k], v) : v}
155
155
  else
156
- other_hash.each { |k, v| self[k] = v }
156
+ other_hash.each {|k, v| self[k] = v}
157
157
  end
158
158
  self
159
159
  end
@@ -164,7 +164,8 @@ class OrderedHash < ::Hash
164
164
  dup.merge!(other_hash, &block)
165
165
  end
166
166
 
167
- # When replacing with another hash, the initial order of our keys must come from the other hash -ordered or not.
167
+ # When replacing with another hash, the initial order of our keys must come from the other hash --
168
+ # ordered or not.
168
169
  def replace(other)
169
170
  super
170
171
  @keys = other.keys
@@ -172,7 +173,7 @@ class OrderedHash < ::Hash
172
173
  end
173
174
 
174
175
  def invert
175
- OrderedHash[self.to_a.map!{|key_value_pair| key_value_pair.reverse}]
176
+ OrderedHash[to_a.map! {|key_value_pair| key_value_pair.reverse}]
176
177
  end
177
178
 
178
179
  def inspect
@@ -180,7 +181,8 @@ class OrderedHash < ::Hash
180
181
  end
181
182
 
182
183
  private
183
- def sync_keys!
184
- @keys.delete_if {|k| !has_key?(k)}
185
- end
184
+
185
+ def sync_keys!
186
+ @keys.delete_if {|k| !has_key?(k)}
187
+ end
186
188
  end