@private
This is used for methods in {Haml::Buffer} that need to be very fast, and take a lot of boolean parameters that are known at compile-time. Instead of passing the parameters in normally, a separate method is defined for every possible combination of those parameters; these are then called using {#static_method_name}.
To define a static method, an ERB template for the method is provided. All conditionals based on the static parameters are done as embedded Ruby within this template. For example:
def_static_method(Foo, :my_static_method, [:foo, :bar], :baz, :bang, <<RUBY) <% if baz && bang %> return foo + bar <% elsif baz || bang %> return foo - bar <% else %> return 17 <% end %> RUBY
{#static_method_name} can be used to call static methods.
@overload def_static_method(klass,
name, args, *vars, erb) @param klass [Module] The class on which to define
the static method @param name [#] The (base) name of the static method
@param args [Array
(**not** to the ERB template)
@param vars [Array
to be made available to the ERB template
@param erb [String] The template for the method code
# File lib/haml/util.rb, line 756 756: def def_static_method(klass, name, args, *vars) 757: erb = vars.pop 758: info = caller_info 759: powerset(vars).each do |set| 760: context = StaticConditionalContext.new(set).instance_eval {binding} 761: klass.class_eval(def #{static_method_name(name, *vars.map {|v| set.include?(v)})}(#{args.join(', ')}) #{ERB.new(erb).result(context)}end, info[0], info[1]) 762: end 763: end
A version of `Enumerable#enum_cons` that works in Ruby 1.8 and 1.9.
@param enum [Enumerable] The enumerable to get the enumerator for @param n [Fixnum] The size of each cons @return [Enumerator] The consed enumerator
# File lib/haml/util.rb, line 639 639: def enum_cons(enum, n) 640: ruby1_8? ? enum.enum_cons(n) : enum.each_cons(n) 641: end
A version of `Enumerable#enum_slice` that works in Ruby 1.8 and 1.9.
@param enum [Enumerable] The enumerable to get the enumerator for @param n [Fixnum] The size of each slice @return [Enumerator] The consed enumerator
# File lib/haml/util.rb, line 648 648: def enum_slice(enum, n) 649: ruby1_8? ? enum.enum_slice(n) : enum.each_slice(n) 650: end
A version of `Enumerable#enum_with_index` that works in Ruby 1.8 and 1.9.
@param enum [Enumerable] The enumerable to get the enumerator for @return [Enumerator] The with-index enumerator
# File lib/haml/util.rb, line 630 630: def enum_with_index(enum) 631: ruby1_8? ? enum.enum_with_index : enum.each_with_index 632: end
Flattens the first `n` nested arrays in a cross-version manner.
@param arr [Array] The array to flatten @param n [Fixnum] The number of levels to flatten @return [Array] The flattened array
# File lib/haml/util.rb, line 665 665: def flatten(arr, n) 666: return arr.flatten(n) unless ruby1_8_6? 667: return arr if n == 0 668: arr.inject([]) {|res, e| e.is_a?(Array) ? res.concat(flatten(e, n - 1)) : res << e} 669: end
Checks to see if a class has a given method. For example:
Haml::Util.has?(:public_instance_method, String, :gsub) #=> true
Method collections like `Class#instance_methods` return strings in Ruby 1.8 and symbols in Ruby 1.9 and on, so this handles checking for them in a compatible way.
@param attr [#] The (singular) name of the method-collection method
(e.g. `:instance_methods`, `:private_methods`)
@param klass [Module] The class to check the methods of which to check @param method [String, Symbol] The name of the method do check for @return [Boolean] Whether or not the given collection has the given method
# File lib/haml/util.rb, line 622 622: def has?(attr, klass, method) 623: klass.send("#{attr}s").include?(ruby1_8? ? method.to_s : method.to_sym) 624: end
Like `Object#inspect`, but preserves non-ASCII characters rather than escaping them under Ruby 1.9.2. This is necessary so that the precompiled Haml template can be `#`d into `@options[:encoding]` before being evaluated.
@param obj {Object} @return {String}
# File lib/haml/util.rb, line 698 698: def inspect_obj(obj) 699: return obj.inspect unless version_geq(::RUBY_VERSION, "1.9.2") 700: return ':' + inspect_obj(obj.to_s) if obj.is_a?(Symbol) 701: return obj.inspect unless obj.is_a?(String) 702: '"' + obj.gsub(/[\x00-\x7F]+/) {|s| s.inspect[1...1]} + '"' 703: end
Haml overrides various `ActionView` helpers, which call an {#is_haml?} method to determine whether or not the current context object is a proper Haml context. Because `ActionView` helpers may be included in non-`ActionView::Base` classes, it’s a good idea to define {#is_haml?} for all objects.
# File lib/haml/helpers.rb, line 604 604: def is_haml? 605: false 606: end
Computes a single longest common subsequence for arrays x and y. Algorithm from [Wikipedia](en.wikipedia.org/wiki/Longest_common_subsequence_problem#Reading_out_an_LCS)
# File lib/haml/util.rb, line 801 801: def lcs_backtrace(c, x, y, i, j, &block) 802: return [] if i == 0 || j == 0 803: if v = yield(x[i], y[j]) 804: return lcs_backtrace(c, x, y, i-1, j-1, &block) << v 805: end 806: 807: return lcs_backtrace(c, x, y, i, j-1, &block) if c[i][j-1] > c[i-1][j] 808: return lcs_backtrace(c, x, y, i-1, j, &block) 809: end
Calculates the memoization table for the Least Common Subsequence algorithm. Algorithm from [Wikipedia](en.wikipedia.org/wiki/Longest_common_subsequence_problem#Computing_the_length_of_the_LCS)
# File lib/haml/util.rb, line 782 782: def lcs_table(x, y) 783: c = Array.new(x.size) {[]} 784: x.size.times {|i| c[i][0] = 0} 785: y.size.times {|j| c[0][j] = 0} 786: (1...x.size).each do |i| 787: (1...y.size).each do |j| 788: c[i][j] = 789: if yield x[i], y[j] 790: c[i-1][j-1] + 1 791: else 792: [c[i][j-1], c[i-1][j]].max 793: end 794: end 795: end 796: return c 797: end
Returns the ASCII code of the given character.
@param c [String] All characters but the first are ignored. @return [Fixnum] The ASCII code of `c`.
# File lib/haml/util.rb, line 656 656: def ord(c) 657: ruby1_8? ? c[0] : c.ord 658: end
Parses a magic comment at the beginning of a Haml file. The parsing rules are basically the same as Ruby’s.
@return [(Boolean, String or nil)]
Whether the document begins with a UTF-8 BOM, and the declared encoding of the document (or nil if none is declared)
# File lib/haml/util.rb, line 817 817: def parse_haml_magic_comment(str) 818: scanner = StringScanner.new(str.dup.force_encoding("BINARY")) 819: bom = scanner.scan(/\xEF\xBB\xBF/) 820: return bom unless scanner.scan(/-\s*#\s*/) 821: if coding = try_parse_haml_emacs_magic_comment(scanner) 822: return bom, coding 823: end 824: 825: return bom unless scanner.scan(/.*?coding[=:]\s*([\w-]+)/n) 826: return bom, scanner[1] 827: end
Tests the hash-equality of two sets in a cross-version manner. Aggravatingly, this is order-dependent in Ruby 1.8.6.
@param set1 [Set] @param set2 [Set] @return [Boolean] Whether or not the sets are hashcode equal
# File lib/haml/util.rb, line 687 687: def set_eql?(set1, set2) 688: return set1.eql?(set2) unless ruby1_8_6? 689: set1.to_a.uniq.sort_by {|e| e.hash}.eql?(set2.to_a.uniq.sort_by {|e| e.hash}) 690: end
Returns the hash code for a set in a cross-version manner. Aggravatingly, this is order-dependent in Ruby 1.8.6.
@param set [Set] @return [Fixnum] The order-independent hashcode of `set`
# File lib/haml/util.rb, line 676 676: def set_hash(set) 677: return set.hash unless ruby1_8_6? 678: set.map {|e| e.hash}.uniq.sort.hash 679: end
Computes the name for a method defined via {#def_static_method}.
@param name [String] The base name of the static method @param vars
[Array
# File lib/haml/util.rb, line 774 774: def static_method_name(name, *vars) 775: "#{name}_#{vars.map {|v| !!v}.join('_')}" 776: end
# File lib/haml/util.rb, line 829 829: def try_parse_haml_emacs_magic_comment(scanner) 830: pos = scanner.pos 831: return unless scanner.scan(/.*?-\*-\s*/) 832: # From Ruby's parse.y 833: return unless scanner.scan(/([^\s'":;]+)\s*:\s*("(?:\\.|[^"])*"|[^"\s;]+?)[\s;]*-\*-/) 834: name, val = scanner[1], scanner[2] 835: return unless name =~ /(en)?coding/n 836: val = $1 if val =~ /^"(.*)"$/ 837: return val 838: ensure 839: scanner.pos = pos 840: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.