2009-11-12 02:17:10 +00:00
---
layout: default
title: Syntax Highlighting Debug
---
2010-03-10 20:22:19 +00:00
< div class = "code_window" >
< em > Ruby< / em >
2009-11-12 16:19:36 +00:00
{% highlight ruby %}
def rebuild_site(relative)
puts ">>> Change Detected to: #{relative} < < < "
IO.popen('rake generate') do |io|
print(io.readpartial(512)) until io.eof?
2009-11-12 02:17:10 +00:00
end
2009-11-12 16:19:36 +00:00
puts '>>> Update Complete < < < '
end
2009-11-12 02:17:10 +00:00
{% endhighlight %}
2010-03-10 20:22:19 +00:00
< / div >
2009-11-12 02:17:10 +00:00
2009-11-12 16:19:36 +00:00
So that's a small example. What about a big one?
2010-03-10 20:22:19 +00:00
< div class = "code_window" >
< em > Ruby< / em >
2009-11-12 16:19:36 +00:00
{% highlight ruby %}
2009-11-12 02:17:10 +00:00
require 'active_support/core_ext/array'
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/object/metaclass'
module ActiveRecord
module NamedScope
extend ActiveSupport::Concern
# All subclasses of ActiveRecord::Base have one named scope:
# * < tt > scoped</ tt > - which allows for the creation of anonymous \scopes, on the fly: < tt > Shirt.scoped(:conditions => {:color => 'red'}).scoped(:include => :washing_instructions)</ tt >
#
# These anonymous \scopes tend to be useful when procedurally generating complex queries, where passing
# intermediate values (scopes) around as first-class objects is convenient.
#
# You can define a scope that applies to all finders using ActiveRecord::Base.default_scope.
included do
named_scope :scoped, lambda { |scope| scope }
end
module ClassMethods
def scopes
read_inheritable_attribute(:scopes) || write_inheritable_attribute(:scopes, {})
end
# Adds a class method for retrieving and querying objects. A scope represents a narrowing of a database query,
# such as < tt > :conditions => {:color => :red}, :select => 'shirts.*', :include => :washing_instructions< / tt > .
#
# class Shirt < ActiveRecord::Base
# named_scope :red, :conditions => {:color => 'red'}
# named_scope :dry_clean_only, :joins => :washing_instructions, :conditions => ['washing_instructions.dry_clean_only = ?', true]
# end
#
# The above calls to < tt > named_scope< / tt > define class methods Shirt.red and Shirt.dry_clean_only. Shirt.red,
# in effect, represents the query < tt > Shirt.find(:all, :conditions => {:color => 'red'})< / tt > .
#
# Unlike < tt > Shirt.find(...)< / tt > , however, the object returned by Shirt.red is not an Array; it resembles the association object
# constructed by a < tt > has_many< / tt > declaration. For instance, you can invoke < tt > Shirt.red.find(:first)< / tt > , < tt > Shirt.red.count< / tt > ,
# < tt > Shirt.red.find(:all, :conditions => {:size => 'small'})< / tt > . Also, just
# as with the association objects, named \scopes act like an Array, implementing Enumerable; < tt > Shirt.red.each(& block)</ tt > ,
# < tt > Shirt.red.first< / tt > , and < tt > Shirt.red.inject(memo, & block)< / tt > all behave as if Shirt.red really was an Array.
#
# These named \scopes are composable. For instance, < tt > Shirt.red.dry_clean_only</ tt > will produce all shirts that are both red and dry clean only.
# Nested finds and calculations also work with these compositions: < tt > Shirt.red.dry_clean_only.count< / tt > returns the number of garments
# for which these criteria obtain. Similarly with < tt > Shirt.red.dry_clean_only.average(:thread_count)< / tt > .
#
# All \scopes are available as class methods on the ActiveRecord::Base descendant upon which the \scopes were defined. But they are also available to
# < tt > has_many< / tt > associations. If,
#
# class Person < ActiveRecord::Base
# has_many :shirts
# end
#
# then < tt > elton.shirts.red.dry_clean_only< / tt > will return all of Elton's red, dry clean
# only shirts.
#
# Named \scopes can also be procedural:
#
# class Shirt < ActiveRecord::Base
# named_scope :colored, lambda { |color|
# { :conditions => { :color => color } }
# }
# end
#
# In this example, < tt > Shirt.colored('puce')< / tt > finds all puce shirts.
#
# Named \scopes can also have extensions, just as with < tt > has_many</ tt > declarations:
#
# class Shirt < ActiveRecord::Base
# named_scope :red, :conditions => {:color => 'red'} do
# def dom_id
# 'red_shirts'
# end
# end
# end
#
#
# For testing complex named \scopes, you can examine the scoping options using the
# < tt > proxy_options< / tt > method on the proxy itself.
#
# class Shirt < ActiveRecord::Base
# named_scope :colored, lambda { |color|
# { :conditions => { :color => color } }
# }
# end
#
# expected_options = { :conditions => { :colored => 'red' } }
# assert_equal expected_options, Shirt.colored('red').proxy_options
def named_scope(name, options = {}, & block)
name = name.to_sym
scopes[name] = lambda do |parent_scope, *args|
Scope.new(parent_scope, case options
when Hash
options
when Proc
options.call(*args)
end, & block)
end
metaclass.instance_eval do
define_method name do |*args|
scopes[name].call(self, *args)
end
end
end
end
class Scope
attr_reader :proxy_scope, :proxy_options, :current_scoped_methods_when_defined
NON_DELEGATE_METHODS = %w(nil? send object_id class extend find size count sum average maximum minimum paginate first last empty? any? many? respond_to?).to_set
[].methods.each do |m|
unless m =~ /^__/ || NON_DELEGATE_METHODS.include?(m.to_s)
delegate m, :to => :proxy_found
end
end
delegate :scopes, :with_scope, :scoped_methods, :to => :proxy_scope
def initialize(proxy_scope, options, & block)
options ||= {}
[options[:extend]].flatten.each { |extension| extend extension } if options[:extend]
extend Module.new(& block) if block_given?
unless Scope === proxy_scope
@current_scoped_methods_when_defined = proxy_scope.send(:current_scoped_methods)
end
@proxy_scope , @proxy_options = proxy_scope, options.except(:extend)
end
def reload
load_found; self
end
def first(*args)
if args.first.kind_of?(Integer) || (@found & & !args.first.kind_of?(Hash))
proxy_found.first(*args)
else
find(:first, *args)
end
end
def last(*args)
if args.first.kind_of?(Integer) || (@found & & !args.first.kind_of?(Hash))
proxy_found.last(*args)
else
find(:last, *args)
end
end
def size
@found ? @found .length : count
end
def empty?
@found ? @found .empty? : count.zero?
end
def respond_to?(method, include_private = false)
super || @proxy_scope .respond_to?(method, include_private)
end
def any?
if block_given?
proxy_found.any? { |*block_args| yield(*block_args) }
else
!empty?
end
end
# Returns true if the named scope has more than 1 matching record.
def many?
if block_given?
proxy_found.many? { |*block_args| yield(*block_args) }
else
size > 1
end
end
protected
def proxy_found
@found || load_found
end
private
def method_missing(method, *args, & block)
if scopes.include?(method)
scopes[method].call(self, *args)
else
with_scope({:find => proxy_options, :create => proxy_options[:conditions].is_a?(Hash) ? proxy_options[:conditions] : {}}, :reverse_merge) do
method = :new if method == :build
if current_scoped_methods_when_defined & & !scoped_methods.include?(current_scoped_methods_when_defined)
with_scope current_scoped_methods_when_defined do
proxy_scope.send(method, *args, & block)
end
else
proxy_scope.send(method, *args, & block)
end
end
end
end
def load_found
@found = find(:all)
end
end
end
end
2010-03-10 20:22:19 +00:00
{% endhighlight %}
< / div >