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
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Kamis, 30 Juni 2011
Additional Range method
Selasa, 28 Juni 2011
array flatten with level for ruby 1.8.7
straight to the code:
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? ;)
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:
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:
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 :)
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 :)
useful online tools for web programming
- Regex for ruby: http://www.rubular.com/
- strftime: http://strfti.me/
- css gradient generator: http://www.colorzilla.com/gradient-editor/
- css validator: http://jigsaw.w3.org/css-validator/
- css rounder corner generator: http://a.deveria.com/roundgen/
- 7 great js resources (not really a tool but useful): http://mashable.com/2011/07/03/7-great-javascript-resources
will be updated as i found another tools
Sabtu, 11 Juni 2011
Rails general coding style
Code:
# somethings_controller.rb def create @something = Something.new params[:something] @something.save! if @something.some_state? @something.initialize_for_some_state end redirect_to success_url rescue render :action => "failed" end
Hint:
- should avoid rescue without specifying the exception, in above code, use
rescue ActiveRecord::RecordInvalid
- better yet, don't use any rescue at all, use save instead of save! with some if
- post processing should be done in callback.
after_create {|something| something.initialize_for_some_state if something.some_state}
Better Code:
# somethings_controller.rb def create @something = Something.new params[:something] if @something.save redirect_to success_url else render :action => "failed" end end
Code:
# somethings_controller.rb def show @something = Something.find(:first, :conditions => "user_id = #{current_user.id} AND id = #{params[:id]} AND name = #{params[:name]}") respond_to do |format| format.html format.js do render :js => "$('#container').html('#{escape_javascript(render :partial => "something", :object => @something)}');" end format.json do render :json => @something.to_json end end end
Hint:
- SQL injection warning! never use data from params or from user input directly in sql code. use something like this instead:
:conditions => ["user_id = #{current_user.id} AND id = ? AND name = ?", params[:id], params[:name]]
- using model relation and dynamic finder you can avoid the conditions entirely
@something = current_user.somethings.find_by_id_and_name params[:id], params[:name]
- you should check if nothing found (@something is nil)
- this is just my opinion, but in most case i'll avoid using respond_to, instead i'll use 3 different view files: show.html.erb, show.js.erb, show.json.erb. rails will automatically use the correct view.
Better Code:
# somethings_controller.rb def show @something = current_user.somethings.find_by_id_and_name params[:id], params[:name] render_invalid "not found" if @something.nil? # read about render_invalid in http://tech.maysora.com/2010/12/rails-renderinvalid-method.html end
to be continued about model
Langganan:
Postingan (Atom)