Create a single bit bitmask.
Bit(0) #=> 1 Bit(1) #=> 2 Bit(2) #=> 4
This is equivalent to n-shift: “1 << n”.
CREDIT: Thomas Sawyer, George Moschovitis
# File lib/facets/integer/bitmask.rb, line 94 def Bit(n) 1 << Integer(n) end
Y-combinator.
f = Y do |n, acc, &b| n < 2 ? acc : b.(n-1, n * acc) end f.call(5, 1) #=> 120
NOTE: This method is not a common core extension and is not loaded automatically when using require 'facets'.
CREDIT: Michael Fellinger
@uncommon
require 'facets/kernel/y'
# File lib/facets/kernel/y.rb, line 19 def Y(*args, &block) y = lambda{|*args| block.call(*args, &y) } end
Similar to __FILE__, __DIR__ provides the directory path to the current executing script.
CREDIT: Trans
# File lib/facets/kernel/__dir__.rb, line 8 def __DIR__(*paths) c = caller.first return nil unless c.rindex(/:\d+(:in `.*')?$/) file = $` # File.dirname(c) return nil if /\A\((.*)\)/ =~ file # eval, etc. #File.expand_path(File.join(File.dirname(file), paths)) File.join(File.dirname(file), paths) end
Retreive the current running method name.
def callee_example __callee__ end callee_example #=> :callee_example
Technically __callee__ should provided alias names, where as __method__ should not. But we’ll have to leave that distinction to Ruby 1.9+.
# File lib/facets/kernel/__method__.rb, line 39 def __callee__ /\`([^\']+)\'/.match(caller(1).first)[1].to_sym end
Shadow method for instance_variable_get.
# File lib/facets/kernel/__get__.rb, line 4 def __get__(ivar) #ivar = "@#{ivar}" unless ivar.to_s[0,1] == '@' instance_variable_get(ivar) end
Retreive the current running method name.
def method_example __method__ end method_example #=> :method_example
Technically __callee__ should provided alias names, where __method__ should not. But we’ll have to leave that distinction to Ruby 1.9+.
# File lib/facets/kernel/__method__.rb, line 17 def __method__ /\`([^\']+)\'/.match(caller(1).first)[1].to_sym end
Shadow method for instance_variable_set.
# File lib/facets/kernel/__get__.rb, line 10 def __set__(ivar, val) #ivar = "@#{ivar}" unless ivar.to_s[0,1] == '@' instance_variable_set(ivar, val) end
Returns a As-functor that allows one to call any ancestor’s method directly of the given object.
class AsExample1 def x ; 1 ; end end class AsExample2 < AsExample1 def x ; 2 ; end end class AsExample3 < AsExample2 def x ; as(AsExample1).x ; end end AsExample1.new.x #=> 1
# File lib/facets/kernel/as.rb, line 22 def as(ancestor, &blk) ##this = self r = As.new(self, ancestor) ##unless r ## r = As.cache[self][ancestor] = Functor.new do |op, *a, &b| ## ancestor.instance_method(op).bind(this).call(*a,&b) ## end ##end r.instance_eval(&blk) if block_given? #yield(r) if block_given? r end
Very simple convenience method to get user input via the console. A prompt will be sent to $stdout, if given, and the input taken from $stdin…
ask "Are you happy? [Yn]"
On the command line one would see…
Are you happy? [Yn]
Responding…
Are you happy? [Yn] Y <ENTER>
The ask method would return “Y”.
# File lib/facets/kernel/ask.rb, line 21 def ask(prompt=nil) $stdout << "#{prompt}" $stdout.flush $stdin.gets.chomp! end
Assign via writer using arguments, hash or associative array.
Using name-value arguments:
object = Object.new object.assign(:a, 1) object.assign(:b, 2)
Using a hash:
object.assign(:a => 1, :b => 2)
Use an associative array:
object.assign([[:a, 1], [:b, 2]])
These are all equivalent to:
object.a = 1 if object.respond_to?(:a=) object.b = 2 if object.respond_to?(:b=)
Using an associative array instead of a hash guarantees order of assignment for older versions of Ruby (< 1.8.7).
TODO: Should this be called set instead? Consider Module#set in this question, and also set_from as the alias of assign_from.
# File lib/facets/kernel/assign.rb, line 33 def assign(data=nil, value=NA) return self unless data if value==NA data.each do |(k,v)| __send__("#{k}=", v) if respond_to?("#{k}=") end else __send__("#{data}=", value) if respond_to?("#{data}=") end self end
Set attribute writers using like readers from another object.
class AssignExample attr_accessor :a, :b def initialize(a, b) @a, @b = a, b end end obj1 = AssignExample.new(1,2) obj2 = AssignExample.new(3,4) obj2.assign_from(obj1, :a, :b) obj2.a #=> 1 obj2.b #=> 2
TODO: Should this be called set_from ?
# File lib/facets/kernel/assign.rb, line 65 def assign_from(obj, *fields) fields.flatten.each do |k| send("#{k}=", obj.__send__("#{k}")) #if self.respond_to?("#{k}=") && obj.respond_to?("#{k}") end end
Create singleton attr_accessors.
obj = Object.new obj.attr_singleton_accessor :x, :y obj.x = 3 obj.y = 4 obj.x #=> 3 obj.y #=> 4
CREDIT: Trans
# File lib/facets/kernel/attr_singleton.rb, line 51 def attr_singleton_accessor(*args) #h, a = *args.partition{|a| Hash===a} (class << self ; self ; end).send( :attr_accessor, *args ) #(class << self ; self ; end).send( :attr_accessor, *h.keys ) #h.each { |k,v| instance_variable_set("@#{k}", v) } end
Creates singleton attr_readers.
obj = Object.new obj.attr_singleton_reader :x, :y attr_singleton_reader :x, :y
CREDIT: Trans
# File lib/facets/kernel/attr_singleton.rb, line 13 def attr_singleton_reader(*args) #h, a = *args.partition{|a| Hash===a} (class << self ; self ; end).send( :attr_reader, *args ) #(class << self ; self ; end).send( :attr_reader, *h.keys ) #h.each { |k,v| instance_variable_set("@#{k}", v) } end
Create singleton attr_writers.
obj = Object.new obj.attr_singleton_writer :x, :y obj.x = 3 obj.y = 4
CREDIT: Trans
# File lib/facets/kernel/attr_singleton.rb, line 31 def attr_singleton_writer(*args) #h, a = *args.partition{|a| Hash===a} (class << self ; self ; end).send( :attr_writer, *args ) #(class << self ; self ; end).send( :attr_writer, *h.keys ) #h.each { |k,v| instance_variable_set("@#{k}", v) } end
An object is blank if it’s nil, empty, or a whitespace string. For example, “”, “ ”, nil, [], and {} are blank.
This simplifies…
if !address.nil? && !address.empty?
to…
if !address.blank?
# File lib/facets/kernel/blank.rb, line 13 def blank? return empty? if respond_to?(:empty?) !self end
Returns true is an object is class TrueClass or FalseClass, otherwise false.
true.bool? #=> true false.bool? #=> true nil.bool? #=> false
# File lib/facets/boolean.rb, line 33 def bool? (true == self or false == self) end
Parse a caller string and break it into its components, returning an array composed of:
For example, from irb
call_stack(1)
produces ...
[["(irb)", 2, :irb_binding], ["/usr/lib/ruby/1.8/irb/workspace.rb", 52, :irb_binding], ["/usr/lib/ruby/1.8/irb/workspace.rb", 52, nil]]
Note: If the user decides to redefine caller() to output data in a different format, prior to requiring this, then the results will be indeterminate.
CREDIT: Trans
# File lib/facets/kernel/call_stack.rb, line 29 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
# File lib/facets/kernel/case.rb, line 3 def case?(*matchers) matchers.all?{ |m| m === self } end
Repeat loop until it yeilds false or nil.
a = [3, 2, 1] b = [] complete do x = a.pop b << x x end b #=> [1, 2, 3, nil]
Be “aware” when using this method, it easy to accidently induce infinite loops.
CREDIT: Trans
# File lib/facets/kernel/complete.rb, line 21 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
CREDIT: Trans
# File lib/facets/kernel/constant.rb, line 14 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
Like p but gives file and line number…
d("hi")
produces …
"hi" (/home/dave/projects/foo.rb, 38)
# File lib/facets/kernel/d.rb, line 11 def d(*x) puts "#{x.inspect} #{caller[0]}" return *x end
# File lib/facets/kernel/deep_copy.rb, line 14 def deep_clone(cache={}) return cache[self] if cache.key?(self) #@deep_cloning_obj if @deep_cloning copy = clone cache[self] = copy #@deep_cloning_obj = clone copy.instance_variables.each do |var| val = instance_variable_get(var) begin #@deep_cloning = true val = val.deep_clone(cache) rescue TypeError next ensure #@deep_cloning = false end copy.instance_variable_set(var, val) #@deep_cloning_obj.instance_variable_set(var, val) end #deep_cloning_obj = @deep_cloning_obj #@deep_cloning_obj = nil #deep_cloning_obj copy end
Anything that can be marshaled can be copied in totality.
"ABC".deep_copy #=> "ABC"
NOTE: Not sure why we wouldn’t just call this copy, but the term deep_copy seems to be the common practive.
# File lib/facets/kernel/deep_copy.rb, line 9 def deep_copy Marshal::load(Marshal::dump(self)) end
Forces the result of a promise to be computed (if necessary) and returns the bare result object. Once evaluated, the result of the promise will be cached. Nested promises will be evaluated together, until the first non-promise result.
If called on a value that is not a promise, it will simply return it.
# File lib/facets/lazy.rb, line 218 def demand( promise ) if promise.respond_to? :__result__ promise.__result__ else # not really a promise promise end 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]
NOTE: This method is not a common core extension and is not loaded automatically when using require 'facets'.
@uncommon
require 'facets/kernel/demo'
# File lib/facets/kernel/demo.rb, line 25 def demo(out=$stdout,&block) out << sprintf("%-25s#=> %s\n", expr = block.call, eval(expr, block.binding).inspect) end
CREDIT: Trans
# File lib/facets/kernel/disable_warnings.rb, line 6 def disable_warnings #:yield: verbose, $VERBOSE = $VERBOSE, nil yield ensure $VERBOSE = verbose end
Call methods on the eigenclass (i.e. the singleton_class).
name = "Tom" name.eigen.define_method(:turkey){ self + " Turkey" } name.turkey #=> "Tom Turkey"
One the nice things you can do with eigen, is define class attributes without having to open a `class << self` block.
c = Class.new do eigen.attr_accessor :a end c.a = 1 c.a #=> 1
NOTE: This was once called `meta`, but meta is such a generic and overly used term that ‘eigen’ was decided upon as a better choice. You can thank or blame _why for the term, if you like.
# File lib/facets/kernel/eigen.rb, line 24 def eigen Functor.new do |op,*a,&b| (class << self; self; end).class_eval do __send__(op,*a,&b) end end end
During this trying time when no one can get their techie catchwords to stick to the refrigerator no matter how hard they slap it with the enchanted magnetic spatula, it’s good to know that the contrived phrases really do fly, graceful and unclasped and bearing north toward chilled shrimp. I know what my Hallowe’en pumpkin is going to say.
NOTE: This method is not a common core extension and is not loaded automatically when using require 'facets'.
CREDIT: WhyTheLuckyStiff
@uncommon
require 'facets/kernel/eigenclass'
# File lib/facets/kernel/eigenclass.rb, line 19 def eigenclass (class << self; self; end) end
CREDIT: Trans
# File lib/facets/kernel/disable_warnings.rb, line 19 def enable_warnings #:yield: verbose, $VERBOSE = $VERBOSE, true yield ensure $VERBOSE = verbose end
Broad equality. Checks to see if the object x is in any way equal to the reciever, starting with the identity equal?, then eql?, then #==, and ending with #===.
1.equate?(1.0) #=> true "string".equate?("string") #=> true String.equate?("string") #=> true
# File lib/facets/kernel/equate.rb, line 11 def equate?(x) equal?(x) || eql?(x) || self == x || self === x end
Yield self -or- return self.
"a".ergo.upcase #=> "A" nil.ergo.foobar #=> nil "a".ergo{ |o| o.upcase } #=> "A" nil.ergo{ |o| o.foobar } #=> nil
This is like tap, but tap yields self and returns self, where as ergo yields self buit return the result.
CREDIT: Daniel DeLorme
# File lib/facets/kernel/ergo.rb, line 18 def ergo(&b) if block_given? b.arity == 1 ? yield(self) : instance_eval(&b) else self end end
Extend an object with a module.
If a block is given, it will be evaluated into an anonymous module and used to extend the object.
obj = Object.new obj.extend do def foo; "foo"; end end obj.foo #=> "foo"
NOTE: This is one of the few core overrides in Facets.
@author Trans @author Marco Otte-Witte (bug fix)
# File lib/facets/kernel/extend.rb, line 24 def extend(*mod, &blk) _extend(*mod) unless mod.empty? _extend Module.new(&blk) if blk self end
Don’t say it!
# File lib/facets/kernel/extension.rb, line 7 def extension class << self; self; end end
Returns true is an object is class FalseClass, otherwise false.
true.false? #=> false false.false? #=> true nil.false? #=> false
# File lib/facets/kernel/true.rb, line 21 def false? (false == self) end
Schedules a computation to be run asynchronously in a background thread and returns a promise for its result. An attempt to demand the result of the promise will block until the computation finishes.
As with Kernel.promise, this passes the block a promise for its own result. Use wisely.
# File lib/facets/lazy.rb, line 233 def future( &computation ) #:yields: result Lazy::Future.new(&computation) end
Send a message to each ancestor in an object’s class hierarchy. The method will only be called if the method is defined for the ancestor.
This can be very useful for setting up a `preinitialize` system.
m = Module.new do attr :a def preinitialize @a = 1 end end c = Class.new do include m def initialize hierarchical_send(:preinitialize) end end c.new.a #=> 1
@todo Include singleton class?
# File lib/facets/kernel/hierarchical_send.rb, line 28 def hierarchical_send(method_name, *args, &block) method_name = method_name.to_s if RUBY_VERSION < '1.9' this = self self.class.hierarchically do |anc| ## is there really no better way to check for the method? if anc.instance_methods(false).include?(method_name) or anc.public_instance_methods(false).include?(method_name) or anc.private_instance_methods(false).include?(method_name) or anc.protected_instance_methods(false).include?(method_name) im = anc.instance_method(method_name) ##im.arity == 0 ? im.bind(this).call(&block) : im.bind(this).call(*args, &block) im.bind(this).call(*args, &block) end end end
Hierarchically apply a block, passing each ancestor to the block starting at the root ancestor and working toward the current object.
# File lib/facets/class/hierarchically.rb, line 6 def hierarchically(&block) ancestors.reverse_each do |m| block.call(m) end end
Is self included in other?
5.in?(0..10) #=> true 5.in?([0,1,2,3]) #=> false
# File lib/facets/kernel/in.rb, line 8 def in?(other) other.include?(self) end
Returns an instance of Instance for self, which allows convenient access to an object’s internals.
# File lib/facets/instance.rb, line 8 def instance INSTANCES[self] ||= Instance.new(self) end
Set instance variables using a hash.
instance_assign('@a'=>1, '@b'=>2) @a #=> 1 @b #=> 2
DEPRECATE: Use instance.update instead of instance_assign.
# File lib/facets/kernel/instance_assign.rb, line 11 def instance_assign(hash) hash.each do |k,v| k = "@#{k}" if k !~ /^@/ instance_variable_set(k, v) end return self end
Easy access to an object qua class, otherwise known as the object’s metaclass or singleton class. This implemnetation alwasy returns the class, even if a block is provided to eval against it…
It is what it is. But I think I like this one best.
CREDIT: Trans
# File lib/facets/kernel/instance_class.rb, line 20 def instance_class(&block) (class << self; self; end).module_eval(&block) if block (class << self; self; end) end
Same as require_all, but for load.
# File lib/facets/kernel/require_all.rb, line 28 def load_all(pattern, safe=nil) c = caller.first fail "Can't parse #{c}" unless c.rindex(/:\d+(:in `.*')?$/) file = $` # File.dirname(c) if /\A\((.*)\)/ =~ file # eval, etc. raise LoadError, "require_relative is called in #{$1}" end glob = File.expand_path(pattern, File.dirname(file)) Dir.glob(glob).each do |absolute| load absolute, safe end end
Load file from same dir as calling script…
load_local 'myscript'
CREDIT: Paul Brannan, Pragmatic Programmers
# File lib/facets/kernel/require_relative.rb, line 35 def load_relative(relative_feature, safe=nil) c = caller.first fail "Can't parse #{c}" unless c.rindex(/:\d+(:in `.*')?$/) file = $` # File.dirname(c) if /\A\((.*)\)/ =~ file # eval, etc. raise LoadError, "require_relative is called in #{$1}" end absolute = File.expand_path(relative_feature, File.dirname(file)) load absolute, safe 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
# File lib/facets/kernel/maybe.rb, line 10 def maybe(chance = 0.5, &block) if block yield if rand < chance else rand < chance end end
Memoize a method.
class MemoExample attr_accessor :a def m memo{ @a } end end ex = MemoExample.new ex.a = 10 ex.m #=> 10 ex.a = 20 ex.m #=> 10
NOTE: This method is not a common core extension and is not loaded automatically when using require 'facets'.
@uncommon
require 'facets/kernel/memo'
# File lib/facets/kernel/memo.rb, line 32 def memo(*args, &block) if args.empty? args = block.binding.eval('[self, __method__]') end if $MEMO.key?(args) $MEMO[args] else $MEMO[args] = block.call end end
Alias a method defined in the metaclass (ie. singleton class).
class MetaExample def self.y?; "y?" ; end end MetaExample.meta_alias "ynot?", "y?" MetaExample.ynot? #=> "y?"
CREDIT: Trans
# File lib/facets/kernel/meta_alias.rb, line 17 def meta_alias(*args) meta_class do alias_method(*args) end end
Easy access to an object’s “special” class, otherwise known as it’s singleton class, eigenclass, adhoc class or object-qua-class.
# File lib/facets/kernel/meta_class.rb, line 6 def meta_class(&block) if block_given? (class << self; self; end).class_eval(&block) else (class << self; self; end) end end
Add method to a meta-class –i.e. a singleton method.
class X; end X.meta_def(:x){"x"} X.x #=> "x"
CREDIT: WhyTheLuckyStiff
# File lib/facets/kernel/meta_def.rb, line 13 def meta_def( name, &block ) meta_class do define_method( name, &block ) end end
Evaluate code in a metaclass. This is equivalent to:
meta_class.instance_eval(...)
CREDIT: WhyTheLuckyStiff
# File lib/facets/kernel/meta_eval.rb, line 11 def meta_eval(str=nil, *file_and_line, &blk) if str meta_class.instance_eval(str, *file_and_line) else meta_class.instance_eval(&blk) end end
The non-underscored form of meta_class if faily common.
Easy access to method as object, and they retain state.
def hello puts "Hello World!" end m1 = method!(:hello) def m1.annotate "simple example" end m2 = method!(:hello) m2.annotate #=> "simple example"
# File lib/facets/kernel/method.rb, line 20 def method!(s) #( @__methods__ ||= {} )[s.to_sym] ||= method(s) $FIRST_CLASS_METHODS[self][s.to_sym] ||= method(s) end
Ask a question expecting a no answer.
# File lib/facets/kernel/yes.rb, line 16 def no?(question) case ask(question).downcase when 'n', 'no' true else false end end
Inversion functor.
true.not.nil? #=> true
# File lib/facets/kernel/not.rb, line 17 def not Functor.new(&method(:not_send).to_proc) end
Same as using NOT operator ‘!’.
true.nil?.not? == !true.nil?
# File lib/facets/kernel/not.rb, line 9 def not? !self end
The opposite of nil?.
"hello".not_nil? # -> true nil.not_nil? # -> false
CREDIT: Gavin Sinclair
# File lib/facets/kernel/not_nil.rb, line 10 def not_nil? ! nil? end
Returns the object id as a string in hexideciaml, which is how Ruby reports them with inspect…
"ABC".object_hexid #=> "0x402d359c"
# File lib/facets/kernel/object_hexid.rb, line 24 def object_hexid HEXID_TEMPLATE % (__id__ << 1) end
Send only to public methods.
class SendExample private def foo; end end obj = SendExample.new expect NoMethodError do obj.object_send(:foo) end
TODO: object_send needs to change for 1.9. Is it public_send ?
CREDIT: Trans
# File lib/facets/kernel/object_send.rb, line 23 def object_send(name, *args, &blk) #instance_eval "self.#{name}(*args)" if respond_to?(name) __send__(name, *args, &blk) else __send__(:method_missing, name, *args, &blk) end end
Alternate to standard p method that outputs Kernel#inspect to stdout, but also passes through the orginal argument(s) …
x = 1 r = 4 + p(1) p r
produces …
1 5
TODO: DEPRECATE as of 1.9, if it will do this.
# File lib/facets/kernel/p.rb, line 18 def p(*x) x.each{ |e| puts e.inspect } #p(*x) x.size > 1 ? x : x.last #x.last end
Returns object if it’s present? otherwise returns nil. object.presence is equivalent to object.present? ? object : nil.
This is handy for any representation of objects where blank is the same as not present at all. For example, this simplifies a common check for HTTP POST/query parameters…
state = params[:state] if params[:state].present? country = params[:country] if params[:country].present? region = state || country || 'US'
becomes…
region = params[:state].presence || params[:country].presence || 'US'
# File lib/facets/kernel/blank.rb, line 38 def presence self if present? end
An object is present if it’s not blank.
# File lib/facets/kernel/blank.rb, line 19 def present? !blank? end
The promise() function is used together with demand() to implement lazy evaluation. It returns a promise to evaluate the provided block at a future time. Evaluation can be demanded and the block’s result obtained via the demand() function.
Implicit evaluation is also supported: the first message sent to it will demand evaluation, after which that message and any subsequent messages will be forwarded to the result object.
As an aid to circular programming, the block will be passed a promise for its own result when it is evaluated. Be careful not to force that promise during the computation, lest the computation diverge.
# File lib/facets/lazy.rb, line 207 def promise( &computation ) #:yields: result Lazy::Promise.new(&computation) end
Easy access to an object qua class, otherwise known as the object’s singleton class. qua_class can also take a block.
string = "Hello World" string.qua_class do def important self + "!" end end string.important #=> "Hello World!"
Yes, another one.
CREDIT: Trans
# File lib/facets/kernel/qua_class.rb, line 20 def qua_class(&block) if block_given? (class << self; self; end).class_eval(&block) else (class << self; self; end) end end
The qua_class method can also be written quaclass.
Require a pattern of files relatvie to the current file. This makes is easy to require an entire directory, for instance:
require_all 'core_ext/*'
NOTE: This method used to allow glob-based requires from the $LOAD_PATH, but this was deprecated in favor of relative requiring only, as it is consider the typical usecase, and globbing from the $LOAD_PATH is a bit dangerous. Better options exist for globbing the $LOAD_PATH such as the plugins gem.
# File lib/facets/kernel/require_all.rb, line 14 def require_all(pattern) c = caller.first fail "Can't parse #{c}" unless c.rindex(/:\d+(:in `.*')?$/) file = $` # File.dirname(c) if /\A\((.*)\)/ =~ file # eval, etc. raise LoadError, "require_relative is called in #{$1}" end glob = File.expand_path(pattern, File.dirname(file)) Dir.glob(glob).each do |absolute| require absolute end end
Require file from same dir as calling script…
require_local 'myscript'
CREDIT: Paul Brannan, Pragmatic Programmers
# File lib/facets/kernel/require_relative.rb, line 11 def require_relative(relative_feature) c = caller.first fail "Can't parse #{c}" unless c.rindex(/:\d+(:in `.*')?$/) file = $` # File.dirname(c) if /\A\((.*)\)/ =~ file # eval, etc. raise LoadError, "require_relative is called in #{$1}" end absolute = File.expand_path(relative_feature, File.dirname(file)) require absolute end
Like respond_to? but returns the result of the call if it does indeed respond.
class RespondExample def f; "f"; end end x = RespondExample.new x.respond(:f) #=> "f" x.respond(:g) #=> nil
or
x.respond.f #=> "f" x.respond.g #=> nil
This method was known as try until Rails defined try to be something more akin to ergo.
CREDIT: Trans, Chris Wanstrath
# File lib/facets/kernel/respond.rb, line 26 def respond(sym=nil, *args, &blk) if sym return nil if not respond_to?(sym) __send__(sym, *args, &blk) else ## TODO: use after 1.8.6 not supported anymore ##Functor.new do |op, *a, &b| ## respond(op, *a, &b) ##end Functor.new(&method(:respond).to_proc) end end
A Ruby-ized realization of the K combinator.
book_class = Struct.new(:title, :author) book = returning book_class.new do |book| book.title = "Imperium" book.author = "Ulick Varange" end book.class #=> book_class
Technically, returning probably should force the return of the stated object irregardless of any return statements that might appear within it’s block. This might differentiate returning from with, however it also would require implementation in Ruby itself.
CREDIT: Mikael Brockman
# File lib/facets/kernel/returning.rb, line 22 def returning(obj=self) #:yield: yield obj obj end
Call parent class/module methods once bound to self.
TODO: Does this have the proper scope for send?
# File lib/facets/kernel/as.rb, line 37 def send_as(ancestor, sym, *args, &blk) ancestor.instance_method(sym).bind(self).call(*args,&blk) end
Silence a stream and/or warnings…
silence(:stdout) do puts "won't see me" end
Supported streams are stderr, stdout, verbose, debug, and warnings, which is the same as verbose. You can also use the actual streams, STDERR and STDOUT.
# File lib/facets/kernel/silence.rb, line 12 def silence(*streams) #:yield: streams = streams.map do |stream| case stream when :stderr STDERR when :stdout STDOUT else stream end end if streams.empty? yield else silence_stream(*streams){ yield } end end
Equivalent to `silence_stream(STDERR)`.
# File lib/facets/kernel/silence.rb, line 63 def silence_stderr #:yeild: silence_stream(STDERR) { yield } end
Equivalent to `silence_stream(STDOUT)`.
# File lib/facets/kernel/silence.rb, line 68 def silence_stdout #:yeild: silence_stream(STDOUT) { yield } end
Silences any stream for the duration of the block…
silence_stream(STDOUT) do puts 'This will never be seen' end puts 'But this will'
CREDIT: David Heinemeier Hansson
# File lib/facets/kernel/silence.rb, line 49 def silence_stream(*streams) #:yeild: on_hold = streams.collect{ |stream| stream.dup } streams.each do |stream| stream.reopen(RUBY_PLATFORM =~ /mswin/ ? 'NUL:' : '/dev/null') stream.sync = true end yield ensure streams.each_with_index do |stream, i| stream.reopen(on_hold[i]) end end
DEPRECATE: Use disable_warnings instead.
Just like silence_stream, but will default to STDOUT, STDERR if no streams are given.
# File lib/facets/kernel/silence.rb, line 34 def silently(*streams) #:yeild: streams = [STDOUT, STDERR] if streams.empty? silence_stream(*streams){ yield } end
Easy access to an object’s “special” class.
NOTE: This is already defined in Ruby 1.9+.
# File lib/facets/kernel/singleton_class.rb, line 6 def singleton_class (class << self; self; end) end
# File lib/facets/kernel/source_location.rb, line 5 def source_location file, line, meth = *caller(1).first.split(':') return file, line end
Returns method of a parent class bound to self.
# File lib/facets/kernel/super_method.rb, line 4 def super_method(klass, meth) unless self.class.ancestors.include?(klass) raise ArgumentError, "Not an ancestor for super_method-- #{klass}" end klass.instance_method(meth).bind(self) end
The tap K-Combinator. This yields self -and- returns self.
Note, Ruby 1.9+ does not support the zero arity instance_eval variation so it has been deprecated.
# File lib/facets/kernel/tap.rb, line 9 def tap #:yield: yield(self) self end
Temporarily set variables while yielding a block, then return the variables to their original settings when complete.
temporarily('$VERBOSE'=>false) do $VERBOSE.assert == false end
# File lib/facets/kernel/temporarily.rb, line 10 def temporarily(settings) #:yield: cache = {} settings.each do |var, val| cache[var] = eval("#{var}") eval("proc{ |v| #{var} = v }").call(val) end yield ensure cache.each do |var, val| eval("proc{ |v| #{var} = v }").call(val) end end
Boolean conversion for not being nil or false. Other classes may redefine this to suite the particular need.
"yes".to_b #=> true "abc".to_b #=> false true.to_b #=> true false.to_b #=> false nil.to_b #=> false
CREDIT: Ara T. Howard, Trans
# File lib/facets/boolean.rb, line 17 def to_b self ? true : false end
All objects except false and nil are “true”.
# File lib/facets/boolean.rb, line 22 def to_bool true end
Calling Kernel#trap() by itself will replace any previously registered handler code. Kernel#trap_chain(), on the other hand, will add the block you supply to the existing “list” of registered handler blocks. Similar to the way Kernel#at_exit() works, Kernel#trap_chain() will prepend the given block to the call chain for the given signal_name. When the signal occurs, your block will be executed first and then the previously registered handler will be invoked. This can be called repeatedly to create a “chain” of handlers.
NOTE: This method is not a common core extension and is not loaded automatically when using require 'facets'.
CREDIT: Tyler Rick
@uncommon
require 'facets/kernel/trap_chain'
# File lib/facets/kernel/trap_chain.rb, line 19 def trap_chain(signal_name, *args, &block) previous_interrupt_handler = trap(signal_name, *args) {} trap(signal_name, *args) do block.call previous_interrupt_handler.call unless previous_interrupt_handler == "DEFAULT" end end
Returns true is an object is class TrueClass, otherwise false.
true.true? #=> true false.true? #=> false nil.true? #=> false
# File lib/facets/kernel/true.rb, line 10 def true? (true == self) end
Invokes the method identified by the symbol method, passing it any arguments and/or the block specified, just like the regular Ruby Object#send does.
Unlike that method however, a NoMethodError exception will not be raised and nil will be returned instead, if the receiving object is a nil object or NilClass.
For example, without try
@example = Struct.new(:name).new("bob") @example && @example.name
or:
@example ? @example.name : nil
But with try
@example.try(:name) #=> "bob"
or
@example.try.name #=> "bob"
It also accepts arguments and a block, for the method it is trying:
@people.try(:collect){ |p| p.name }
# File lib/facets/kernel/try.rb, line 35 def try(method=nil, *args, &block) if method __send__(method, *args, &block) else self end end
Tests to see if something has value. An object is considered to have value if it is not nil? and if it responds to empty?, is not empty.
nil.val? #=> false [].val? #=> false 10.val? #=> true [nil].val? #=> true
# File lib/facets/kernel/val.rb, line 12 def val? return false if nil? return false if empty? if respond_to?(:empty?) true end
Like returning but exectues the block via instance_eval.
def foo with values = [] do self << 'bar' self << 'baz' end end foo # => ['bar', 'baz']
# File lib/facets/kernel/with.rb, line 15 def with(obj=self, &block) obj.instance_eval(&block) end
Returns an Array of methods ending in ‘=’.
class WritersExample attr_reader :a, :b attr_accessor :x, :y private def q=(q); @q=q; end end w = WritersExample.new syms = w.writers # [:x=, :y=] syms.include?(:x=) #=> true syms.include?(:y=) #=> true
If the chomp option is true, then the trailing ‘=’ will be removed.
syms = w.writers(:chomp=>true) syms.include?(:x) #=> true syms.include?(:y) #=> true
By default writers only includes public methods. To see private or protected methods use the :access option.
w.writers(:access=>:private) #=> [:q=]
Or multiple access options,
syms = w.writers(:access=>[:public,:private]) # [:q=,:x=,:y=] syms.include?(:q=) #=> true syms.include?(:x=) #=> true syms.include?(:y=) #=> true
You can simply supply `:all` to get all method regardless accessibility.
Also, by default this method excludes all writers defined in Object or Kernel. To include these set ancestors to Object or Kernel.
w.writers(Object)
TODO: Create Module#instance_writers.
# File lib/facets/kernel/writers.rb, line 48 def writers(*ancestors_and_options) options = (Hash === ancestors_and_options.last ? ancestors_and_options.pop : {}) chomp = options[:chomp] access = options[:access] || [] ancestors = ancestors_and_options.first access = [access].flatten if access.include?(:all) access.concat([:public, :protected, :private]) end access << :public if access.empty? writers = [] if access.include?(:private) writers += private_methods(ancestors).select{ |m| /=$/ =~ m.to_s } end if access.include?(:protected) writers += protected_methods(ancestors).select{ |m| /=$/ =~ m.to_s } end if access.include?(:public) writers += public_methods(ancestors).select{ |m| /=$/ =~ m.to_s } end if ancestors == Kernel exclude = nil elsif ancestors == Object exclude = Kernel else exclude = Object end if exclude kernel_writers = exclude.instance_methods.select{ |m| /=$/ =~ m.to_s } writers = writers - kernel_writers end writers = writers.map{ |w| w.to_s.chomp('=') } if chomp writers.map{ |w| w.to_sym } end
Generated with the Darkfish Rdoc Generator 2.