Ruby content_tag(已修改):第1部分(app helper)

def content_tag(name, *options, &proc)
	content = options.shift unless options.first.is_a?(Hash)
	content ||= nil
	options = options.shift
	if block_given?
		concat("<#{name}#{tag_options(options.stringify_keys) if options}>", proc.binding)
		yield(content)
		concat("</#{name}>", proc.binding)
	elsif content.nil?
		"<#{name}#{tag_options(options.stringify_keys) if options} />"
	else
		super(name, content, options)
	end
end

Ruby 没有安全的吸气剂

class SafeGetter
  attr_accessor :receiver
  
  def self.safe_nil
    @safe_nil ||= SafeGetter.new(nil)  
  end
  
  def initialize(r)
    @receiver = r
  end
  
  def to_s
    @receiver.to_s
  end
  
  def method_missing(methodname, *args)
    (@receiver.respond_to? methodname) ? SafeGetter.new(@receiver.send(methodname)) : SafeGetter.safe_nil
  end
end

# SafeGetter.new(@user).course.book.title.name.to_s => ''

Ruby 格式化字符串,如PRINT USING

require 'strscan'

class String

  # Returns the string formatted according to a pattern.
  #
  # The pattern consists of placeholders and literals. The string is placed in
  # the placeholders, leaving the literals as they are. The result may be
  # truncated or padded if there are more placeholders than strings.
  #
  # Placeholders are '#' or '&'. Each '#' is replaced by one character from
  # the string, or the filler character if the string has no characters left.
  # The '&' is replaced by any remaining characters, or left out of the result
  # if there are no remaining characters. There can only be one '&' in the
  # pattern. If there is no '&' and more characters than placeholders, the
  # remaining characters are discarded.
  # 
  # '#' or '&' may be replaced by other characters if they are needed as
  # literals.
  #
  # Examples:
  # "123456789".using('###-##-####')
  #    => "123-45-6789"
  # "12345".using('###-##-####')
  #    => "123-45"
  # "12345".using('###-##-####', nil)
  #    => "12345"
  # "12345".using('###-##-####', ' ')
  #    => "123-45-    "
  # "873555121276668".using ('(###) ###-#### ext &', '', true)
  #    => "(873) 555-1212 ext 76668"
  # "8735551212".using ('(###) ###-#### ext &', '', true)
  #    => "(873) 555-1212"
  # "5551212".using ('(###) ###-#### ext &', '', true)
  #    => "555-1212"
  # "KB5774X".using ('##-&-#')
  #    => "KB-5774-X"
  #
  # Parameters:
  # pattern -- The format string, see above.
  # fill    -- A string for padding. If the empty string, then the pattern is
  #            filled as much as possible, and the rest of the pattern is
  #            truncated. If nil, and the pattern cannot be filled exactly,
  #            the string is returned unchanged. If some other string, the
  #            pattern is filled as much as possible and the remainder is 
  #            padded with the string. Defaults to the empty string.
  # right   -- If true, the pattern is filled from right-to-left instead of
  #            from left-to-right, and truncated on the left instead of the
  #            right if needed. Default is false.
  # fixchar -- The single-character placeholder. Default is '#'.
  # remchar -- The remaining-character placeholder. Default is '&'.
  #
  def using(pattern, fill='', right=false, fixchar='#', remchar='&')

    remCount = pattern.count(remchar)
    raise ArgumentError.new("Too many #{remchar}") if remCount > 1
    raise ArgumentError.new("#{fixchar} too long") if fixchar.length > 1
    raise ArgumentError.new("#{remchar} too long") if remchar.length > 1
    raise ArgumentError.new("#{fill} too long")    if fill.length > 1
    remaining = remCount != 0
    slots = pattern.count(fixchar)

    # Return the string if it doesn't fit and we shouldn't even try,
    if fill.nil?
      return self if self.length < slots
      return self if self.length > slots and !remaining
    end

    # Pad and clone the string if necessary.
    source =  if fill.nil? || fill.empty? then
                self
              elsif right then
                self.rjust(slots, fill)
              else
                self.ljust(slots, fill)
              end
    
    # Truncate the string if necessary.
    if source.length > slots && !remaining then
      source = right ? source[-source.length, source.length] :
                       source[0, source.length]
    end

    # Truncate pattern if needed.
    if !fill.nil? && fill.empty? then
      
      if source.length < slots  # implies '&' can be ignored
        keepCount = source.length # Number of placeholders we are keeping
        leftmost, rightmost = 0, pattern.length - 1
        if right then
          # Look right-to-left until we find the last '#' to keep.
          # Loop starts at 1 because 0th placeholder is in the inject param.
          leftmost = (1...keepCount).inject(pattern.rindex(fixchar)) {
            |leftmost, n| pattern.rindex(fixchar, leftmost - 1) }
        else
          # Look left-to-right until we find the last '#' to keep.
          rightmost = (1...keepCount).inject(pattern.index(fixchar)) {
            |rightmost, n| pattern.index(fixchar, rightmost + 1) }
        end
        pattern = pattern[leftmost..rightmost]
        slots = pattern.count(fixchar)
      end
    
      # Trim empty '&' up to nearest placeholder. If a '&' at the end goes
      # empty, the literals between it and the nearest '#' are probably also
      # unnecessary.
      if source.length == slots then
        if pattern.match("^#{Regexp.escape(remchar)}") then
          pattern = pattern[pattern.index(fixchar) || 0 ... pattern.length]
        elsif pattern.match("#{Regexp.escape(remchar)}$") then
          pattern = pattern[0 ... (pattern.rindex(fixchar) + fixchar.length) || pattern.length]
        end
      end

    end
      
    # Figure out how long the remainder will be when we get to it.
    remSize = source.length - slots
    if remSize < 0 then remSize = 0; end
    
    # Make the result.
    scanner = ::StringScanner.new(pattern)
    sourceIndex = 0
    result = ''
    fixRegexp = Regexp.new(Regexp.escape(fixchar))
    remRegexp = Regexp.new(Regexp.escape(remchar))
    while not scanner.eos?
      if scanner.scan(fixRegexp) then
        result += source[sourceIndex].chr
        sourceIndex += 1
      elsif scanner.scan(remRegexp) then
        result += source[sourceIndex, remSize]
        sourceIndex += remSize
      else
        result += scanner.getch
      end
    end
    
    result
  end
end

Ruby 寻呼机用于大量数据

class ActionController::AbstractRequest
  def get_post_params
    self.parameters.reject {|k,v| k == 'controller' || k == 'action'}
  end
end

def pagerBar(paginator, anchor)
  page = paginator.current_page;
  pageParam = 'page';
  firstPage = 1;
  lastPage = paginator.page_count;
  prevStr = '←';
  nextStr = '→';
  elideStr = '… ';   # Include trailing space.
  pageSpan = 3;      # How many pages to the left and right of current.
  
  # The central group of pages.
  window = page.window(pageSpan);
  windowFirst = window.first.number;
  windowLast = window.last.number;
  
  # These define the halfway pages.
  prevHalfway = (windowFirst / 2.0).floor;
  prevHalfway = 2 if prevHalfway == 1;
  nextHalfway = ((windowLast + lastPage) / 2.0).ceil;
  nextHalfway = lastPage - 1 if nextHalfway == lastPage;
  
  # Need to show first/last pages separate from range?
  showFirst = (windowFirst > 1);
  showLast = (windowLast < lastPage);
  
  # Need to show half-way pages?
  showPrevHalfway = (prevHalfway > 1 && prevHalfway < windowFirst);
  showNextHalfway = (nextHalfway < lastPage && nextHalfway > windowLast);
  
  # Pages missing before/after half-way pages?
  elideBeforePrevHalf = (showPrevHalfway && (prevHalfway - firstPage) > 1);
  elideAfterPrevHalf = (showPrevHalfway && (windowFirst - prevHalfway) > 1);
  elideBeforeNextHalf = (showNextHalfway && (nextHalfway - windowLast) > 1);
  elideAfterNextHalf = (showNextHalfway && (lastPage - nextHalfway) > 1);
  
  # No half-way pages, but pages missing before/after range?
  elideBeforeRange = (!showPrevHalfway && (windowFirst - firstPage) > 1);
  elideAfterRange = (!showNextHalfway && (lastPage - windowLast) > 1);
  
  # Do prev arrow.
  html = link_to_unless(page.first?, prevStr,
    request.get_post_params.merge(
      { pageParam => page.previous, :anchor => anchor }));
  html += ' ';
  
  # Do first page.
  if (showFirst)
    html += link_to(paginator.first_page.number.to_s,
      request.get_post_params.merge(
        { pageParam => paginator.first_page.number, :anchor => anchor }));
    html += ' ';
  end
  
  # Do prev halfway point.
  html += elideStr if elideBeforePrevHalf;
  if (showPrevHalfway)
    html += link_to(paginator[prevHalfway].number.to_s,
      request.get_post_params.merge(
        { pageParam => paginator[prevHalfway].number, :anchor => anchor }));
    html += ' ';
  end
  html += elideStr if elideAfterPrevHalf;
  
  # Do range.
  html += elideStr if elideBeforeRange;
  window.pages.each do |windowPage|
    html += link_to_unless (page == windowPage, windowPage.number.to_s,
      request.get_post_params.merge(
        { pageParam => windowPage.number, :anchor => anchor }));
    html += ' ';
  end
  html += elideStr if elideAfterRange;
  
  # Do next halfway point.
  html += elideStr if elideBeforeNextHalf;
  if (showNextHalfway)
    html += link_to(paginator[nextHalfway].number.to_s,
      request.get_post_params.merge(
        { pageParam => paginator[nextHalfway].number, :anchor => anchor }));
    html += ' ';
  end
  html += elideStr if elideAfterNextHalf;
  
  # Do last page.
  if (showLast)
    html += link_to(paginator.last_page.number.to_s,
      request.get_post_params.merge(
        { pageParam => paginator.last_page.number, :anchor => anchor }));
    html += ' ';
  end
      
  # Do next arrow.
  html += link_to_unless(page.last?, nextStr,
    request.get_post_params.merge(
      { pageParam => page.next, :anchor => anchor }));
    
  # Return
  html
end

Ruby 谢勒的例子

class GnuPackage < BasePackage
  def initialize()
    super()

    @base = "#{@name}-${version}"
    @tarball = "#{@base}.tar.bz2"
    @url = "ftp://ftp.gnu.org/pub/gnu/#{@name}/#{@tarball}"
    @dir = @base
    @build_dir = "#{@name}-build"
  end

end

class BinutilsPackage < GnuPackage
  def initialize()
    @version = "2.17"
    @name = "binutils"
    super()

    @config_opts = "--disable-nls --with-sysroot=\"#{$sys_root}\" --enable-shared --disable-multilib"
  end

  def build
    block("build") do
      run "cd #{$build_dir}"
      run "mkdir -p #{@build_dir}"
      run "cd #{@build_dir}"
      configure "script" => "../#{@dir}/configure", "opts" => @config_opts
      run "make configure-host"
      run "make"
    end
  end

  def install
    block("install") do
      run "cd #{$build_dir}"
      run "cd #{@build_dir}"
      run "make install"
    end
  end
end

binutils = BinutilsPackage.new
binutils.download "/tmp"
binutils.extract
binutils.build
binutils.install

Ruby 从URL获取链接

%w[uri net/http rexml/document].each{|l|require l};(REXML::Document.new(Net::HTTP.get_response(URI.parse(ARGV[0])).read_body)).elements.each("//a/@href").collect{|l|l.to_s}.sort!.uniq!.each{|l|puts l}

Ruby ios7crypt.rb

#!/usr/bin/env ruby

# Author:: Andrew Pennebaker
# Copyright:: Copyright 2007 Andrew Pennebaker
# License:: GPL
#
# == Synopsis
#
# ios7crypt: encrypts and decrypts passwords with Cisco IOS7 algorithm
#
# == Usage
#
# ios7crypt [OPTIONS]
#
# --help, -h:
#    show help
#
# --encrypt, -e <password1> <password2> <password3> ...:
#    prints out the encrypted passwords as hashes
#
# --decrypt, -d <hash1> <hash2> <hash3> ...:
#    prints out the decrypted hashes as passwords

require "getoptlong"
require "rdoc/usage"

$xlat=[
	0x64, 0x73, 0x66, 0x64, 0x3b, 0x6b, 0x66, 0x6f,
	0x41, 0x2c, 0x2e, 0x69, 0x79, 0x65, 0x77, 0x72,
	0x6b, 0x6c, 0x64, 0x4a, 0x4b, 0x44, 0x48, 0x53,
	0x55, 0x42, 0x73, 0x67, 0x76, 0x63, 0x61, 0x36,
	0x39, 0x38, 0x33, 0x34, 0x6e, 0x63, 0x78, 0x76,
	0x39, 0x38, 0x37, 0x33, 0x32, 0x35, 0x34, 0x6b,
	0x3b, 0x66, 0x67, 0x38, 0x37
]

def encrypt(password)
	seed=rand(16)
	password=password[0, 11]

	hash=(0 .. (password.length-1)).collect { |i| $xlat[(seed+i)%$xlat.length] ^ password[i] }

	return format("%02d", seed) + hash.collect { |e| format("%02x", e) }.join("")
end

def decrypt(hash)
	seed=hash[0, 2].to_i

	hash=hash[2, hash.length-1]

	pairs=(0 .. (hash.length/2-1)).collect { |i| hash[i*2, 2].to_i(16) }

	decrypted=(0 .. (pairs.length-1)).collect { |i| $xlat[(seed+i)%$xlat.length] ^ pairs[i] }

	return (decrypted.collect { |e| e.chr }).join("")
end

opts=GetoptLong.new(
	["--help", "-h", GetoptLong::NO_ARGUMENT],
	["--encrypt", "-e", GetoptLong::NO_ARGUMENT],
	["--decrypt", "-d", GetoptLong::NO_ARGUMENT]
)

mode = :help

opts.each do |option, value|
	case option
		when "--help"
			RDoc::usage
		when "--encrypt"
			mode = :encrypt
		when "--decrypt"
			mode = :decrypt
	end
end

case mode
	when :help
		RDoc::usage
	when :encrypt
		ARGV.each { |arg| puts encrypt(arg) }
	when :decrypt
		ARGV.each { |arg| puts decrypt(arg) }
end

Ruby VietnameseAnalyzer.rb

require 'unicode'

# Normalizes token text to lower case.
class UnicodeLowerCaseFilter
  def initialize(token_stream)
    @input = token_stream
  end
  
  def text=(text)
    @input.text = text   
  end
  
  def next()
    t = @input.next()
    
    if (t == nil)
      return nil
    end
    
    t.text = Unicode.downcase(t.text)
    return t
  end
end

class VietnameseAnalyzer < Ferret::Analysis::Analyzer
  include Ferret::Analysis
  
  # Standard Character mappings to remove all special characters
  # so only default ASCII characters get indexed
  CHARACTER_MAPPINGS = {
    ['á','à','ạ','ả','ã','ă','ắ','ằ','ặ','ẳ','ẵ','â','ấ','ầ','ậ','ẩ','ẫ'] => 'a',
    ['Ä‘'] => 'd',
    ['é','è','ẹ','ẻ','ẽ','ê','ế','ề','ệ','ể','ễ'] => 'e',
    ['í','ì','ị','ỉ','ĩ'] => 'i',
    ['ó','ò','ọ','ủ','õ','ơ','ớ','ờ','ợ','ở','ỡ','ô','ố','ồ','ộ','ổ','ỗ'] => 'o',
    ['ú','ù','ụ','ů','ũ','ư','ứ','ừ','ự','ử','ữ'] => 'u',
    ['ý','ỳ','ỵ','ỷ','ỹ'] => 'y',
  } unless defined?(CHARACTER_MAPPINGS)
  
  def token_stream(field, str)
    ts = StandardTokenizer.new(str)
    ts = UnicodeLowerCaseFilter.new(ts)
    ts = MappingFilter.new(ts, CHARACTER_MAPPINGS)
  end
end

Ruby 发送主要

# send email with :login
  def send_email(subject, message)
   
    from='sender@sender_address.de'
    from_alias='the sender'
    to='recipient@recip_address.de'
    to_alias='the recipient'
    smtp_host='smtp.1und1.com'
    port=25	# default port is 25
    user='username'
    password='its_a_secret'

    myMessage = <<END_OF_MESSAGE
From: #{from_alias} <#{from}>
To: #{to_alias} <#{to}>
Subject: #{subject}

#{message}
END_OF_MESSAGE

    Net::SMTP.start(smtphost, port, from, user, password, :login) do |smtp|
      smtp.send_message myMessage, from, to
    end
  end

Ruby 浮点数到十进制数

def f_to_dec(f, prec=2,sep='.')
  f.to_i.to_s+sep+((prec-(post=((f*(10**prec)).to_i%(10**prec)).to_s).size).times do post='0'+post end; post)
end