- __DIR__
- __as__
- __callee__
- __method__
- __quaclass__
- __self__
- __singleton__
- __singleton_class__
- as
- assign_from
- assign_with
- autoreload
- autoreload_files
- autoreload_glob
- bool?
- bug!
- cache
- call_stack
- called
- complete
- constant
- copy
- deep_copy
- demo
- eigenclass
- false?
- generate_method_name
- get_by_id
- in?
- instance_assign
- instvar
- instvar!
- maybe
- method!
- methods
- nack
- new
- object_hexid
- op_esc
- own
- p
- pp_exception
- quaclass
- require_all
- require_esc
- require_facet
- require_local
- resc
- respond
- returning
- send_as
- set_from
- set_with
- silence_warnings
- silently
- singleton
- singleton_class
- super_method
- supermethod
- this
- true?
- unuri
- uri
- warn_with_line
OPERATORS | = | %w{ +@ -@ + - ** * / % ~ <=> << >> < > === == =~ <= >= | & ^ []= [] } |
OPERATORS_REGEXP | = | Regexp.new( '(' << OPERATORS.collect{ |k| Regexp.escape(k) }.join('|') << ')' ) |
OPERATORS_ESC_TABLE | = | { "+@" => "op_plus_self", "-@" => "op_minus_self", "+" => "op_plus", "-" => "op_minus", "**" => "op_pow", "*" => "op_mul", "/" => "op_div", "%" => "op_mod", "~" => "op_tilde", "<=>" => "op_cmp", "<<" => "op_lshift", ">>" => "op_rshift", "<" => "op_lt", ">" => "op_gt", "===" => "op_case_eq", "==" => "op_equal", "=~" => "op_apply", "<=" => "op_lt_eq", ">=" => "op_gt_eq", "|" => "op_or", "&" => "op_and", "^" => "op_xor", "[]=" => "op_store", "[]" => "op_fetch" |
Similar to FILE and LINE, DIR provides the directory path to the current executing script.
[ show source ]
# File lib/facets/core/kernel/__DIR__.rb, line 7 def __DIR__ (/^(.+)?:\d+/ =~ caller[0]) ? File.dirname($1) : nil end
Returns a Functor that allows one to call any parent method directly.
class A def x ; 1 ; end end class B < A def x ; 2 ; end end class C < B def x ; as(A).x ; end end C.new.x #=> 1
[ show source ]
# File lib/facets/core/kernel/as.rb, line 22 def __as__( klass=nil, &blk ) selfclass = Kernel.instance_method(:class).bind(self).call klass ||= selfclass.superclass if selfclass.ancestors.include?(klass) Functor.new do |meth, *args| # &blk| klass.instance_method(meth).bind(self).call(*args) # ,&blk) end else raise ArgumentError, "#{klass} is not an ancestor" end end
Alias for quaclass
Returns a Functor that allows one to call any Kernel or Object method bound to self, making it possible to bypass overrides of Kernel and Object methods.
class A def object_id ; "OBTUSE" ; end end c = C.new c.object_id #=> "OBTUSE" c.__self__.object_id #=> 6664875832
[ show source ]
# File lib/facets/core/kernel/__self__.rb, line 24 def __self__ @__self__ ||= Functor.new do |meth, *args| # &blk| Object.instance_method(meth).bind(self).call(*args) # ,&blk) end end
Alias for singleton
Alias for singleton_class
Set instance vars using another object.
class O attr_accessor :d def initialize( a, b, c, d) @a = a @b = b @c = c @d = d end end o1 = O.new(1,2,3,4) o2 = O.new(0,0,0,0) o2.assign_from( o1, '@a', '@b', '@c', '@d' ) o2.instance_eval{ @a } #=> 1 o2.instance_eval{ @b } #=> 2 o2.instance_eval{ @c } #=> 3 o2.instance_eval{ @d } #=> 4
See also assign_with.
[ show source ]
# File lib/facets/core/kernel/assign_from.rb, line 27 def assign_from(obj, *fields) force = false case fields.last when true, false, nil force = fields.pop end unless fields.empty? fields.each do |k| var = k.to_s var = var.slice(0,1) == '@' ? var : "@#{var}" if obj.instance_variables.include?(var) self.instance_variable_set( var, obj.instance_variable_get(var) ) end end else if force fields = obj.instance_variables else fields = instance_variables | obj.instance_variables end fields.each do |var| instance_variable_set( var, obj.instance_variable_get(var) ) end end return self end
Set setter methods and/or vars using a hash (or assoc array). assign_with is a meta-programming method, which allows you to use a hash to do any kind of variable assignment and/or setting:
For example, assuming that there is an accessor defined as d:
assign_with( '@a'=>1, '@@b'=>2, '$c'=>3, 'd'=>4 ) @a #=> 1 @@b #=> 2 $c #=> 3 d #=> 4
Note that while the global variable is strictly unnecessary, it works for completeness sake.
[ show source ]
# File lib/facets/core/kernel/assign_with.rb, line 32 def assign_with(*args) harg = args.last.is_a?(Hash) ? args.pop : {} unless args.empty? # if not assoc array, eg. [ [], [], ... ] # preserves order of opertation unless args[0].is_a?(Array) i = 0; a = [] while i < args.size a << [ args[i], args[i+1] ] i += 2 end args = a end end args.each do |k,v| instance_assign( k, v ) end harg.each do |k,v| instance_assign( k, v ) end return self end
Autoreload feature files.
Automatically reload, at regular intervals, any previously loaded features, and/or other files not already loaded, if they have been modified since the last interval check. A numeric parameter sets the reload interval in seconds and the file parameter can either be a glob string or an array of file paths. If a glob string, it is expanded only once on the initial method call. Supplying a boolean parameter of ‘false’ will force autreload to skip previously loaded features and only reload the specified files. Also keeps a "dirty" flag.
[ show source ]
# File lib/facets/core/kernel/autoreload.rb, line 19 def autoreload( *args ) check_interval=10 include_features = true files = nil args.each do |arg| case arg when Numeric check_interval = arg when String files = Dir.glob( arg ) when Array files = arg when TrueClass, FalseClass include_features = arg end end file_mtime = {} Thread.new(Time.now) do |start_time| loop do sleep check_interval if include_features feature_files = $LOADED_FEATURES.collect { |feature| $LOAD_PATH.each { |lp| file = File.join(lp, feature) } }.flatten feature_files.each { |file| if File.exists?(file) and (mtime = File.stat(file).mtime) > (file_mtime[file] || start_time) $autoreload_dirty = true file_mtime[file] = mtime STDERR.puts "File '#{ file }' reloaded" begin load(file) rescue Exception => e STDERR.puts e.inspect end end } end if files files.each do |file| if File.exists?(file) and (mtime = File.stat(file).mtime) > (file_mtime[file] || start_time) $autoreload_dirty = true file_mtime[file] = mtime STDERR.puts "File '#{ file }' changed" end end end end end end
Same as autoreload, but does not include previously loaded features. This is equivalent to as adding a ‘false’ parameter to autoreload.
[ show source ]
# File lib/facets/core/kernel/autoreload.rb, line 82 def autoreload_files( *args ) autoreload( *args, false ) end
Alias for autoreload_files
Returns true is an object is class TrueClass or FalseClass, otherwise false.
true.bool? #=> true false.bool? #=> true nil.bool? #=> false
[ show source ]
# File lib/facets/core/kernel/bool.rb, line 36 def bool? (true == self or false == self) end
Raises a ScritBug error with a message.
if find_bug then bug! "unknown bug found" end
[ show source ]
# File lib/facets/core/kernel/bug.rb, line 14 def bug!( message = 'must not happen' ) raise ScriptBug, "\n[SCRIPT BUG] " + message end
Object#cache is essentially like Module#memoize except it can also be used on singleton/eigen methods. OTOH, memoize’s implementation is arguably better for it’s use of bind instead of alias. Eventually the two implmenations will be reconciled with a single implmentation.
[ show source ]
# File lib/facets/core/kernel/cache.rb, line 10 def cache m = nil if m (Module === self ? self : (class << self; self; end)).module_eval "alias_method '__\#{ m }__', '\#{ m }'\ndef \#{ m }(*__a__,&__b__)\nc = cache['\#{ m }']\nk = [__a__,__b__]\nif c.has_key? k\nc[k]\nelse\nc[k] = __\#{ m }__(*__a__,&__b__)\nend\nend\n" end @cache ||= Hash::new{|h,k| h[k]={}} end
[ show source ]
# File lib/facets/core/kernel/call_stack.rb, line 23 def call_stack( level = 1 ) call_str_array = pp_call_stack(level) stack = [] call_str_array.each{ |call_str| file, lineno, method = call_str.split(':') if method =~ /in `(.*)'/ then method = $1.intern() end stack << [file, lineno.to_i, method] } stack end
[ show source ]
# File lib/facets/core/kernel/complete.rb, line 3 def complete loop { break unless yield } end
This is similar to +Module#const_get+ but is accessible at all levels, and, unlike const_get, can handle module hierarchy.
constant("Fixnum") # -> Fixnum constant(:Fixnum) # -> Fixnum constant("Process::Sys") # -> Process::Sys constant("Regexp::MULTILINE") # -> 4 require 'test/unit' Test.constant("Unit::Assertions") # -> Test::Unit::Assertions Test.constant("::Test::Unit") # -> Test::Unit
[ show source ]
# File lib/facets/core/kernel/constant.rb, line 17 def constant(const) const = const.to_s.dup base = const.sub!(/^::/, '') ? Object : ( self.kind_of?(Module) ? self : self.class ) const.split(/::/).inject(base){ |mod, name| mod.const_get(name) } end
Anything that can be marshaled can be copied in totality. This is also commonly called a deep_copy.
"ABC".copy #=> "ABC"
[ show source ]
# File lib/facets/core/kernel/copy.rb, line 9 def copy Marshal::load(Marshal::dump(self)) end
Anything that can be marshaled can be copied in totality. This is also just called copy.
"ABC".deep_copy #=> "ABC"
[ show source ]
# File lib/facets/core/kernel/deep_copy.rb, line 9 def deep_copy Marshal::load(Marshal::dump(self)) end
For debugging and showing examples. Currently this takes an argument of a string in a block.
demo {%{ a = [1,2,3] }} demo {%{ a.slice(1,2) }} demo {%{ a.map { |x| x**3 } }}
Produces:
a = [1,2,3] #=> [1, 2, 3] a.slice(1,2) #=> [2, 3] a.map { |x| x**3 } #=> [1, 8, 27]
[ show source ]
# File lib/facets/core/kernel/demo.rb, line 23 def demo(out=$stdout,&block) out << sprintf("%-25s#=> %s\n", expr = block.call, eval(expr, block.binding).inspect) end
[ show source ]
# File lib/facets/core/kernel/eigenclass.rb, line 14 def eigenclass (class << self; self; end) end
Returns true is an object is class FalseClass, otherwise false.
true.false? #=> false false.false? #=> true nil.false? #=> false
[ show source ]
# File lib/facets/core/kernel/bool.rb, line 25 def false? (false == self) end
Generates a new symbol that is unique among the method names of the object. If a name argument is given, it will generate a similar name.
Class.generate_method_name( :class ) => :_clast_
[ show source ]
# File lib/facets/core/kernel/generate_method_name.rb, line 10 def generate_method_name( name='a' ) s = name.to_s while self.respond_to?( "_#{s}_" ) s = s.succ end return "_#{s}_".to_sym end
[ show source ]
# File lib/facets/core/kernel/get_by_id.rb, line 6 def get_by_id( id ) ObjectSpace._id2ref( id ) end
Is self included in other?
5.in?(0..10) #=> true 5.in?([0,1,2,3]) #=> false
[ show source ]
# File lib/facets/core/kernel/in.rb, line 9 def in?(other) other.include?(self) end
Universal assignment. This is a meta-programming method, which allows you to assign any type of variable.
[ show source ]
# File lib/facets/core/kernel/instance_assign.rb, line 7 def instance_assign( name, value ) k = name.to_s v = value /^([@$]{0,2})/ =~ k case $1 when '$', '@@' instance_eval %Q{ #{k} = v } when '@' instance_variable_set( k, v ) else return __send__( "#{k}=", v ) if respond_to?("#{k}=") # No accessor? What to do? Assume instance var, or error? ... self.instance_variable_set( "@#{k}", v ) end return value end
[ show source ]
# File lib/facets/core/kernel/instvar.rb, line 5 def instvar( sym ) instance_variable_get( "@#{sym}" ) end
[ show source ]
# File lib/facets/core/kernel/instvar.rb, line 9 def instvar!( sym, val ) instance_variable_set( "@#{sym}", val ) end
Random generator that returns true or false. Can also take a block that has a 50/50 chance to being executed.
maybe #=> true maybe #=> false
[ show source ]
# File lib/facets/core/kernel/maybe.rb, line 10 def maybe(chance = 0.5, &block) if block then yield if rand < chance else rand < chance end end
Easy access to method as objects, and they retain state!
def hello puts "Hello World!" end p method!(:hello) #=> <Method: #hello>
[ show source ]
# File lib/facets/core/kernel/method.rb, line 39 def method!(s) ( @__methods__ ||= {} )[s] ||= method(s) end
Returns a list of methods according to symbol(s) given.
Usable symbols include:
- :inherited or :ancestors
- :local or :no_ancestors
- :public
- :private
- :protected
- :singleton
- :all
It no symbol is given then :public is assumed. Unrecognized symbols raise an error.
def test puts("Hello World!") end methods(:local) #=> ['test']
[ show source ]
# File lib/facets/core/kernel/methods.rb, line 26 def methods(*args) args = [ :public, :local, :ancestors ] if args.empty? m = self.class.instance_methods( *args ) m |= singleton_methods if args.include?( :singleton ) or args.include?( :all ) m end
[ show source ]
# File lib/facets/core/kernel/nack.rb, line 9 def nack; NackClass.new ; end
Synonymous with clone, this is an interesting method in that it promotes prototype-based Ruby. Now Classes aren’t the only things that respond to new.
"ABC".new => "ABC"
[ show source ]
# File lib/facets/core/kernel/new.rb, line 10 def new self.clone end
Returns the object id as a string in hexideciaml, which is how Ruby reports them with inspect.
"ABC".object_hexid #=> "0x402d359c"
[ show source ]
# File lib/facets/core/kernel/object_hexid.rb, line 9 def object_hexid return "0x" << ('%.x' % (2*self.__id__))[1..-1] end
[ show source ]
# File lib/facets/core/kernel/op_esc.rb, line 33 def op_esc( str ) str.gsub(OPERATORS_REGEXP){ OPERATORS_ESC_TABLE[$1] } end
Easy access to an object’s specialized class, otherwise known as it’s metaclass or singleton class.
[ show source ]
# File lib/facets/core/kernel/own.rb, line 7 def own(&blk) (class << self; self; end).module_eval( &blk ) if blk return (class << self; self; end) end
alias_method :pr, :p
REdefines standrard #p kernel method to pass through its argument.
[ show source ]
# File lib/facets/core/kernel/p.rb, line 7 def p( x ) puts x.inspect x end
Pretty prints an exception/error object usefull for helpfull debug messages
Input: The Exception/StandardError object
Output: the pretty printed string
[ show source ]
# File lib/facets/core/kernel/pp_exception.rb, line 13 def pp_exception(ex) return %{#{ex.message}\n #{ex.backtrace.join("\n ")}\n LOGGED FROM: #{caller[0]}} end
Easy access to an object qua class, otherwise known as the object’s metaclass or singleton class.
It is what it is. -- transonoma
[ show source ]
# File lib/facets/core/kernel/quaclass.rb, line 11 def quaclass( &block ) (class << self; self; end).module_eval(&block) if block (class << self; self; end) end
Provides a shortcut to the Regexp.escape module method.
[ show source ]
# File lib/facets/core/kernel/resc.rb, line 5 def resc(x) Regexp.escape(x) end
Like respond_to? but returns the result of the call if it does respond.
(This is used to be called respond_with_value.)
[ show source ]
# File lib/facets/core/kernel/respond.rb, line 9 def respond(sym, *args) return nil if not respond_to?(sym, *args) send(sym, *args) end
A Ruby-ized realization of the K combinator.
def foo returning values = [] do values << 'bar' values << 'baz' end end foo # => ['bar', 'baz']
[ show source ]
# File lib/facets/core/kernel/returning.rb, line 18 def returning(value) yield value end
Call parent class/module methods once bound to self.
[ show source ]
# File lib/facets/core/kernel/send_as.rb, line 6 def send_as(klass, meth, *args, &blk) selfclass = Kernel.instance_method(:class).bind(self).call raise ArgumentError if ! selfclass.ancestors.include?(klass) klass.instance_method(meth).bind(self).call(*args, &blk) end
Set setter methods using a another object.
class X attr_accessor :a, :b def initialize( a, b ) @a,@b = a,b end end obj1 = X.new( 1, 2 ) obj2 = X.new obj2.set_from(obj1) obj2.a #=> 1 obj2.b #=> 2
[ show source ]
# File lib/facets/core/kernel/set_from.rb, line 22 def set_from(obj, *fields) unless fields.empty? fields.each do |k| send( "#{k}=", obj.send("#{k}") ) #if self.respond_to?("#{k}=") && obj.respond_to?("#{k}") end else setters = methods.collect { |m| m =~ /=$/ } setters.each do |setter| getter = setter.chomp('=') if obj.respond_to?(getter) send( setter, obj.send(getter) ) fields < getter end end end fields end
Assign via setter methods using a hash (or assoc array).
object.set_with( :a => 1, :b => 2 ) object.set_with( :a, 1, :b, 2 ) object.set_with( [:a, 1], [:b, 2] ) object.set_with( *[[:a, 1], [:b, 2]] )
These are all the same as doing:
object.a = 1 object.b = 2
The array forms gaurentees order of operation.
[ show source ]
# File lib/facets/core/kernel/set_with.rb, line 19 def set_with(*args) harg = args.last.is_a?(Hash) ? args.pop : {} unless args.empty? # if not assoc array, eg. [ [], [], ... ] # preserves order of opertation unless args[0].is_a?(Array) i = 0; a = [] while i < args.size a << [ args[i], args[i+1] ] i += 2 end args = a end end args.each do |k,v| self.send( "#{k}=", v ) #if respond_to?("#{k}=") end harg.each do |k,v| self.send( "#{k}=", v ) #if respond_to?("#{k}=") end end
Alias for silently
Temporarily turn-off verbose mode while yielding block.
[ show source ]
# File lib/facets/core/kernel/silently.rb, line 6 def silently #:yield: old_verbose, $VERBOSE = $VERBOSE, nil begin yield ensure $VERBOSE = old_verbose end end
Access to an object’s "special" class, otherwise known as it’s eigenclass or metaclass or own, etc.
One day these names must be reconciled!
[ show source ]
# File lib/facets/core/kernel/singleton.rb, line 9 def singleton (class << self; self; end) end
Access to an object’s "special" class, otherwise known as it’s eigenclass or metaclass or own, etc.
One day these names must be reconciled!
[ show source ]
# File lib/facets/core/kernel/singleton_class.rb, line 9 def singleton_class (class << self; self; end) end
Alias for supermethod
Returns method of a parent class bound to self.
[ show source ]
# File lib/facets/core/kernel/supermethod.rb, line 6 def supermethod(klass, meth) unless self.class.ancestors.include?(klass) raise ArgumentError end klass.instance_method(meth).bind(self) end
Returns true is an object is class TrueClass, otherwise false.
true.true? #=> true false.true? #=> false nil.true? #=> false
[ show source ]
# File lib/facets/core/kernel/bool.rb, line 14 def true? (true == self) end
[ show source ]
# File lib/facets/core/kernel/uri.rb, line 9 def unuri( s ) URI.unescape( s ) end
[ show source ]
# File lib/facets/core/kernel/uri.rb, line 5 def uri( s, w=%r{[^a-zA-Z_0-9./-]} ) URI.escape( s, w ) end
Like warn produces the current line number as well.
warn_with_line("You have been warned.")
produces
3: Warning: You have been warned.
Note that this method depends on the output of caller.
[ show source ]
# File lib/facets/core/kernel/warn_with_line.rb, line 13 def warn_with_line(msg="", fulltrace=nil) trace = caller(1) where = trace[0].sub(/:in.*/,'') STDERR.puts "#{where}: Warning: #{msg}" STDERR.puts trace.map { |t| "\tfrom #{t}" } if fulltrace end
Retreive the current running method name.
There is a lot of debate on what to call this. me returns a symbol, not a string.
def tester; __method__; end tester #=> :tester
[ show source ]
# File lib/facets/core/kernel/__method__.rb, line 14 def __method__ /\`([^\']+)\'/.match(caller(1).first)[1].to_sym end
Retreive the current running method name. There is a lot of debate on what to call this. called differs from method_name only by the fact that it returns a symbol, rather then a string.
def tester; called; end tester #=> :tester
[ show source ]
# File lib/facets/core/kernel/called.rb, line 14 def called /\`([^\']+)\'/.match(caller(1).first)[1].to_sym end
Require a pattern of files. This make is easy to require an entire directory, for instance.
require_all 'facet/time/*'
[ show source ]
# File lib/facets/core/kernel/require_all.rb, line 11 def require_all( pat ) $LOAD_PATH.each do |path| fs = Dir[File.join(path,pat)] unless fs.empty? fs.each { |f| Kernel.require( f ) unless File.directory?( f ) } break; end end end
Require a file with puncuation marks escaped using NANOESC table.
require_esc '[].rb'
in actuality requires the file ‘op_fetch.rb’.
[ show source ]
# File lib/facets/core/kernel/require_esc.rb, line 13 def require_esc( fpath ) fdir, fname = File.split(fpath) ename = op_esc( fname ) case ename[-1,1] ; when '!','=','?' then ename = ename[0...-1] ; end epath = File.join( fdir, ename ) require( epath ) end
Just like require_esc excapt that it provides the initial ‘facet/’ path.
require_facet 'string/capitalized?'
_is the same as_
require_esc 'facet/string/capitalized?'
[ show source ]
# File lib/facets/core/kernel/require_facet.rb, line 16 def require_facet( fpath ) require_esc( "facet/#{fpath}" ) end
Require file from same dir as calling script.
require_local 'templib'
[ show source ]
# File lib/facets/core/kernel/require_local.rb, line 10 def require_local( fname ) #fdir = File.expand_path( File.dirname( caller[0] ) ) fdir = File.dirname( caller[0] ) require( File.join( fdir, fname ) ) end
Returns the method object of the current method.
[ show source ]
# File lib/facets/core/kernel/this.rb, line 7 def this name = /\`([^\']+)\'/.match(caller(1).first)[1] return method(name) end