# util.rb

Path: | lib/haml/util.rb
Last Update: | Sat Jun 12 14:55:25 +0000 2010

### Required files

erb set enumerator stringio strscan haml/root haml/util/subset_map

### Methods

def_static_method enum_cons enum_slice enum_with_index flatten has? ord set_eql? set_hash static_method_name

### Public Instance methods

def_static_method(klass, name, args, *vars)

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 [to_s] The (base) name of the static method @param args [Array<Symbol>] The names of the arguments to the defined methods

      (**not** to the ERB template)

@param vars [Array<Symbol>] The names of the static boolean variables

      to be made available to the ERB template

@param erb [String] The template for the method code

[Source]

         # File lib/haml/util.rb, line 680
    680:     def def_static_method(klass, name, args, *vars)
    681:       erb = vars.pop
    682:       info = caller_info
    683:       powerset(vars).each do |set|
    684:         context = StaticConditionalContext.new(set).instance_eval {binding}
    685:         klass.class_eval("def \#{static_method_name(name, *vars.map {|v| set.include?(v)})}(\#{args.join(', ')})\n  \#{ERB.new(erb).result(context)}\nend\n", info[0], info[1])
    686:       end
    687:     end

enum_cons(enum, n)

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

[Source]

         # File lib/haml/util.rb, line 576
    576:     def enum_cons(enum, n)
    577:       ruby1_8? ? enum.enum_cons(n) : enum.each_cons(n)
    578:     end

enum_slice(enum, n)

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

[Source]

         # File lib/haml/util.rb, line 585
    585:     def enum_slice(enum, n)
    586:       ruby1_8? ? enum.enum_slice(n) : enum.each_slice(n)
    587:     end

enum_with_index(enum)

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

[Source]

         # File lib/haml/util.rb, line 567
    567:     def enum_with_index(enum)
    568:       ruby1_8? ? enum.enum_with_index : enum.each_with_index
    569:     end

flatten(arr, n)

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

[Source]

         # File lib/haml/util.rb, line 602
    602:     def flatten(arr, n)
    603:       return arr.flatten(n) unless ruby1_8_6?
    604:       return arr if n == 0
    605:       arr.inject([]) {|res, e| e.is_a?(Array) ? res.concat(flatten(e, n - 1)) : res << e}
    606:     end

has?(attr, klass, method)

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 [to_s] 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

[Source]

         # File lib/haml/util.rb, line 559
    559:     def has?(attr, klass, method)
    560:       klass.send("#{attr}s").include?(ruby1_8? ? method.to_s : method.to_sym)
    561:     end

ord(c)

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`.

[Source]

         # File lib/haml/util.rb, line 593
    593:     def ord(c)
    594:       ruby1_8? ? c[0] : c.ord
    595:     end

set_eql?(set1, set2)

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

[Source]

         # File lib/haml/util.rb, line 624
    624:     def set_eql?(set1, set2)
    625:       return set1.eql?(set2) unless ruby1_8_6?
    626:       set1.to_a.uniq.sort_by {|e| e.hash}.eql?(set2.to_a.uniq.sort_by {|e| e.hash})
    627:     end

set_hash(set)

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`

[Source]

         # File lib/haml/util.rb, line 613
    613:     def set_hash(set)
    614:       return set.hash unless ruby1_8_6?
    615:       set.map {|e| e.hash}.uniq.sort.hash
    616:     end

static_method_name(name, *vars)

Computes the name for a method defined via \{def_static_method}.

@param name [String] The base name of the static method @param vars [Array<Boolean>] The static variable assignment @return [String] The real name of the static method

[Source]

         # File lib/haml/util.rb, line 699
    699:     def static_method_name(name, *vars)
    700:       "#{name}_#{vars.map {|v| !!v}.join('_')}"
    701:     end

[Validate]