1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170
|
require 'thread'
require 'rbconfig'
# --------------------------------------------------------------------------
class String
# call-seq:
# shrink( width, ellipses = '...' ) #=> string
#
# Shrink the size of the current string to the given _width_ by removing
# characters from the middle of the string and replacing them with
# _ellipses_. If the _width_ is greater than the length of the string, the
# string is returned unchanged. If the _width_ is less than the length of
# the _ellipses_, then the _ellipses_ are returned.
#
def shrink( width, ellipses = '...')
raise ArgumentError, "width cannot be negative: #{width}" if width < 0
return self if length <= width
remove = length - width + ellipses.length
return ellipses.dup if remove >= length
left_end = (length + 1 - remove) / 2
right_start = left_end + remove
left = self[0,left_end]
right = self[right_start,length-right_start]
left << ellipses << right
end
end
# --------------------------------------------------------------------------
class Module
# call-seq:
# logger_name #=> string
#
# Returns a predictable logger name for the current module or class. If
# used within an anonymous class, the first non-anonymous class name will
# be used as the logger name. If used within a meta-class, the name of the
# actual class will be used as the logger name. If used within an
# anonymous module, the string 'anonymous' will be returned.
#
def logger_name
return name unless name.nil? or name.empty?
# check if this is a metaclass (or eigenclass)
if ancestors.include? Class
inspect =~ %r/#<Class:([^#>]+)>/
return $1
end
# see if we have a superclass
if respond_to? :superclass
return superclass.logger_name
end
# we are an anonymous module
::Logging.log_internal(-2) {
'cannot return a predictable, unique name for anonymous modules'
}
return 'anonymous'
end
end
# --------------------------------------------------------------------------
class File
# Returns <tt>true</tt> if another process holds an exclusive lock on the
# file. Returns <tt>false</tt> if this is not the case.
#
# If a <tt>block</tt> of code is passed to this method, it will be run iff
# this process can obtain an exclusive lock on the file. The block will be
# run while this lock is held, and the exclusive lock will be released when
# the method returns.
#
# The exclusive lock is requested in a non-blocking mode. This method will
# return immediately (and the block will not be executed) if an exclusive
# lock cannot be obtained.
#
def flock?
status = flock(LOCK_EX|LOCK_NB)
case status
when false; true
when 0; block_given? ? yield : false
else
raise SystemCallError, "flock failed with status: #{status}"
end
ensure
flock LOCK_UN
end
# Execute a <tt>block</tt> in the context of a shared lock on this file. A
# shared lock will be obtained on the file, the block executed, and the lock
# released.
#
def flock_sh
flock LOCK_SH
yield
ensure
flock LOCK_UN
end
# :stopdoc:
conf = defined?(RbConfig) ? RbConfig::CONFIG : Config::CONFIG
if conf['host_os'] =~ /mswin|windows|cygwin|mingw/i
# don't lock files on windows
undef :flock?, :flock_sh
def flock?() yield; end
def flock_sh() yield; end
end
# :startdoc:
end
# --------------------------------------------------------------------------
module FileUtils
# Concatenate the contents of the _src_ file to the end of the _dest_ file.
# If the _dest_ file does not exist, then the _src_ file is copied to the
# _dest_ file using +copy_file+.
#
def concat( src, dest )
if File.exist?(dest)
bufsize = File.stat(dest).blksize || 8192
buffer = String.new
File.open(dest, 'a') { |d|
File.open(src, 'r') { |r|
while bytes = r.read(bufsize, buffer)
d.syswrite bytes
end
}
}
else
copy_file(src, dest)
end
end
module_function :concat
end
# --------------------------------------------------------------------------
class ReentrantMutex < Mutex
def initialize
super
@locker = nil
end
alias_method :original_synchronize, :synchronize
def synchronize
if @locker == Thread.current
yield
else
original_synchronize {
begin
@locker = Thread.current
yield
ensure
@locker = nil
end
}
end
end
end # ReentrantMutex
|