Halaman

Senin, 03 Oktober 2011

install mysql2 > 0.3.6 for mysql 64bit in windows

gem install mysql2 --platform=ruby -- '--with-mysql-lib="C:\Program Files\MySQL\MySQL Server 5.5\lib" --with-mysql-include="C:\Program Files\MySQL\MySQL Server 5.5\include"'

http://dev.mysql.com/downloads/connector/c/

copy  C:\mysql-connector-c-noinstall-6.0.2-win32\lib\libmysql.dll to ruby\bin

original source: http://blog.mmediasys.com/2011/07/07/installing-mysql-on-windows-7-x64-and-using-ruby-with-it/

Senin, 04 Juli 2011

fixing option tag display none bug in webkit

The Problem

option tag using style display:none isn't hidden in browser using webkit engine (chrome, safari)
https://bugs.webkit.org/show_bug.cgi?id=8351

The workaround

using jQuery js framework with one simple function taken from jquery.extended_helper_2.6:
(function($) {
  $.fn.extend({
    /* hide select's specified option by removing the option and storing it in variable
     * this function is a workaround to fix webkit bug when hiding select's option:
     * https://bugs.webkit.org/show_bug.cgi?id=8351
     * hideSelectOptions(selector, options)
     * selector:
     * - string selector of options to hide
     * - null or undefined will not hide any options
     * - empty string will hide all options
     * - function will be ran for all options, return true to hide the options
     * options:
     * - toggleHide: true/false, activate/deactive toggle hide/show select if all options is hidden
     * - placeholder: string, add placeholder option if all options is hidden
     * usage:
     *  - $('select.certain_class').hideSelectOptions('.another_class'); // -> show previously hidden options and hide all options with 'another_class' class
     *  - $('select.certain_class').hideSelectOptions(''); // -> hide all options
     *  - $('select.certain_class').hideSelectOptions(); // -> show previously hidden options without hiding any options
     */
    hideSelectOptions: function(selector, options){
      if(!options) options = {};
      this.filter('select').each(function(){
        var $this = $(this);
        // restore previously hidden options and remove any placeholder option
        $this.append($this.data('hiddenOptions')).find('.placeholder_option').remove();

        // return if no selector specified
        if(!selector) return;
        
        // find, detach and store specified hidden options
        var hidden_options = $this.find('option');
        if($.isFunction(selector))
          hidden_options = hidden_options.deleteIf(function(){return !selector.call(this);});
        else
          hidden_options = hidden_options.filter(selector);
        $this.data('hiddenOptions',
          hidden_options
            .removeAttr('selected')
            .detach());

        // find visible options
        var visible_options = $this.find('option');

        // toggle hide/show select depend on visible option found
        if(options.toggleHide)
          $this.toggle(visible_options.length);
        if(options.placeholder && !visible_options.length)
          $this.append('');

        // select first option if no other visible option selected and trigger select change
        if(!visible_options.filter(':selected').length){
          visible_options.filter(':first').attr('selected', 'selected');
          $this.trigger('change');
        }
      });
      return this;
    }
  });
})(jQuery);

The Demonstration

Kamis, 30 Juni 2011

Additional Range method

class Range
  # return true if 2 range overlapped
  def overlap? other_range
    include?(other_range.begin) || other_range.include?(self.begin)
  end

  # return a new intersection range between two ranges
  def & other_range
    raise TypeError, "exclusive range can't be intersected with non-exclusive one" unless self.exclude_end? == other_range.exclude_end?
    new_begin = [self.begin, other_range.begin].max
    new_end = [self.end, other_range.end].min
    new_begin <= new_end ? Range.new(new_begin, new_end, self.exclude_end?) : nil
  end

  # return true if other_range is a subset in self
  def contains? other_range
    if !exclude_end?
      include?(other_range.begin) && include?(other_range.end)
    elsif self.begin.respond_to?('>=')
      self.begin <= other_range.begin && self.end.send(other_range.exclude_end? ? '>=' : '>', other_range.end)
    else
      raise TypeError, "can't determine inclusion of range with this type of members"
    end
  end

  # return true if self is a subset of other_range
  def within? other_range
    other_range.contains? self
  end

  # return length of the range (only for subtract-able range)
  def length
    self.end.respond_to?('-') ? self.end - self.begin : nil
  end

  # return next range with same span (only for subtract-able and add-able range)
  def succ allow_touch=false
    return nil unless self.end.respond_to?('-') && self.end.respond_to?('+')
    new_begin = allow_touch || exclude_end? || !self.end.respond_to?(:succ) ? self.end : self.end.succ
    new_end = new_begin + length
    Range.new(new_begin, new_end, exclude_end?)
  end

  # return previous range with same span (only for subtract-able and add-able range)
  def pred allow_touch=false
    return nil unless self.end.respond_to?('-') && self.begin.respond_to?('+')
    new_end = allow_touch || exclude_end? || !self.begin.respond_to?(:pred) ? self.begin : self.begin.pred
    new_begin = new_end - length
    Range.new(new_begin, new_end, exclude_end?)
  end
end

Selasa, 28 Juni 2011

array flatten with level for ruby 1.8.7

straight to the code:
class Array
  alias_method :orig_flatten, :flatten
  
  def flatten level=nil
    if level.is_a?(Integer)
      temp_arr = clone
      level.times{ |i| temp_arr = temp_arr.inject([]){|s,v| v.is_a?(Array) ? s.concat(v) : s << v} }
      temp_arr
    else
      orig_flatten
    end
  end
end

of course although untested i'm sure it will have worse performance than the original flatten in ruby 1.9.2, but better than nothing right? ;)

ruby array to hash method

update 2012-12-21:
you should use flat_map instead of flatten, i'm too lazy to update the code though.. :P

we can convert hash to array easily using .to_a method for example:
hsh = {:a => 1, :b => 2, :c => 3}
arr = hsh.to_a # -> [[:a, 1], [:b, 2], [:c, 3]]

but there's no built in method to reverse that, there's no .to_hash instance method for array.

to solve that i added a simple instance method for array:
class Array
  def to_hash values=nil
    Hash[*(values.is_a?(Array) ? self.zip(values) : self).flatten(1)]
  end
end

hsh = {:a => 1, :b => 2, :c => 3}
arr = hsh.to_a # -> [[:a, 1], [:b, 2], [:c, 3]]
arr.to_hash == hsh # -> true
[:a,:b,:c].to_hash [1,2,3] # -> {:a => 1, :b => 2, :c => 3}

a little precaution, flatten(1) will not work properly in ruby 1.8.7 or older, therefore it won't be possible to create hash with array as key or value. but there's a simple workaround for that by overriding array flatten method to behave like ruby 1.9.2 in my next post :)