Module: Kernel

Defined in:
lib/core/facets/boolean.rb,
lib/core/facets/kernel/d.rb,
lib/core/facets/kernel/p.rb,
lib/core/facets/kernel/y.rb,
lib/core/facets/kernel/as.rb,
lib/core/facets/kernel/in.rb,
lib/core/facets/kernel/ask.rb,
lib/core/facets/kernel/not.rb,
lib/core/facets/kernel/tap.rb,
lib/core/facets/kernel/try.rb,
lib/core/facets/kernel/val.rb,
lib/core/facets/kernel/yes.rb,
lib/core/facets/kernel/case.rb,
lib/core/facets/kernel/demo.rb,
lib/core/facets/kernel/ergo.rb,
lib/core/facets/kernel/here.rb,
lib/core/facets/kernel/like.rb,
lib/core/facets/kernel/memo.rb,
lib/core/facets/kernel/meta.rb,
lib/core/facets/kernel/true.rb,
lib/core/facets/kernel/with.rb,
lib/core/facets/kernel/blank.rb,
lib/core/facets/kernel/maybe.rb,
lib/core/facets/kernel/assign.rb,
lib/core/facets/kernel/extend.rb,
lib/core/facets/kernel/method.rb,
lib/core/facets/kernel/__dir__.rb,
lib/core/facets/kernel/__get__.rb,
lib/core/facets/kernel/not_nil.rb,
lib/core/facets/kernel/respond.rb,
lib/core/facets/kernel/silence.rb,
lib/core/facets/kernel/writers.rb,
lib/core/facets/integer/bitmask.rb,
lib/core/facets/kernel/complete.rb,
lib/core/facets/kernel/meta_def.rb,
lib/core/facets/kernel/__class__.rb,
lib/core/facets/kernel/callstack.rb,
lib/core/facets/kernel/deep_copy.rb,
lib/core/facets/kernel/extension.rb,
lib/core/facets/kernel/identical.rb,
lib/core/facets/kernel/meta_eval.rb,
lib/core/facets/kernel/qua_class.rb,
lib/core/facets/kernel/returning.rb,
lib/core/facets/kernel/deep_clone.rb,
lib/core/facets/kernel/eigenclass.rb,
lib/core/facets/kernel/meta_alias.rb,
lib/core/facets/kernel/meta_class.rb,
lib/core/facets/kernel/trap_chain.rb,
lib/core/facets/kernel/object_send.rb,
lib/core/facets/kernel/require_all.rb,
lib/core/facets/kernel/temporarily.rb,
lib/core/facets/kernel/object_class.rb,
lib/core/facets/kernel/object_hexid.rb,
lib/core/facets/kernel/super_method.rb,
lib/core/facets/class/hierarchically.rb,
lib/core/facets/kernel/instance_send.rb,
lib/core/facets/kernel/load_relative.rb,
lib/core/facets/kernel/attr_singleton.rb,
lib/core/facets/kernel/instance_class.rb,
lib/core/facets/kernel/instance_assign.rb,
lib/core/facets/kernel/singleton_class.rb,
lib/core/facets/kernel/disable_warnings.rb,
lib/core/facets/kernel/instance_extract.rb,
lib/core/facets/kernel/instance_replace.rb,
lib/core/facets/kernel/hierarchical_send.rb,
lib/standard/facets/cli.rb,
lib/standard/facets/thread.rb,
lib/standard/facets/thread.rb,
lib/standard/facets/nullclass.rb,
lib/standard/facets/yaml/kernel.rb,
lib/standard/facets/load_monitor.rb,
lib/core/facets/lazy.rb

Constant Summary collapse

ARCH_SIZE =
(['a'].pack('P').length > 4 ? 64 : 32)
HEXID_TEMPLATE =
"0x%x"

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.ask(prompt = nil) ⇒ Object

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”.



21
22
23
24
25
# File 'lib/core/facets/kernel/ask.rb', line 21

def ask(prompt=nil)
  $stdout << "#{prompt}"
  $stdout.flush
  $stdin.gets.chomp!
end

.load(file, wrap = false) ⇒ Object

Load script and print what is being loaded.



19
20
21
22
# File 'lib/standard/facets/load_monitor.rb', line 19

def load(file, wrap=false)
  $stderr.puts "monitor load: #{file}\n#{caller.inspect}\n\n"
  load_without_monitor(file, wrap)
end

.load_without_monitorObject



4
# File 'lib/standard/facets/load_monitor.rb', line 4

alias_method :load_without_monitor, :load

.require(file) ⇒ Object

Require script and print what is being require.



11
12
13
14
# File 'lib/standard/facets/load_monitor.rb', line 11

def require(file)
  $stderr.puts "monitor require: #{file}\n#{caller.inspect}\n\n"
  require_without_monitor(file)
end

.require_without_monitorObject



3
# File 'lib/standard/facets/load_monitor.rb', line 3

alias_method :require_without_monitor, :require

Instance Method Details

#__DIR__(*paths) ⇒ Object

Similar to __FILE__, __DIR__ provides the directory path to the current executing script.

DEPRECATED: As of Ruby 2.0, which will have #__dir__ method.

CREDIT: Trans



10
11
12
13
14
15
16
17
# File 'lib/core/facets/kernel/__dir__.rb', line 10

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

#__get__(ivar) ⇒ Object

Shadow method for instance_variable_get.



4
5
6
7
# File 'lib/core/facets/kernel/__get__.rb', line 4

def __get__(ivar)
  #ivar = "@#{ivar}" unless ivar.to_s[0,1] == '@'
  instance_variable_get(ivar)
end

#__set__(ivar, val) ⇒ Object

Shadow method for instance_variable_set.



10
11
12
13
# File 'lib/core/facets/kernel/__get__.rb', line 10

def __set__(ivar, val)
  #ivar = "@#{ivar}" unless ivar.to_s[0,1] == '@'
  instance_variable_set(ivar, val)
end

#as(ancestor, &blk) ⇒ Object

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


22
23
24
25
26
27
28
29
30
31
32
# File 'lib/core/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

#ask(prompt = nil) ⇒ Object (private)

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”.



21
22
23
24
25
# File 'lib/core/facets/kernel/ask.rb', line 21

def ask(prompt=nil)
  $stdout << "#{prompt}"
  $stdout.flush
  $stdin.gets.chomp!
end

#assign(data = nil, value = NA) ⇒ Object

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.



33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/core/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

#assign_from(obj, *fields) ⇒ Object

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 ?



65
66
67
68
69
# File 'lib/core/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

#attr_singleton_accessor(*args) ⇒ Object

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



51
52
53
54
55
56
# File 'lib/core/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

#attr_singleton_reader(*args) ⇒ Object

Creates singleton attr_readers.

obj = Object.new

obj.attr_singleton_reader :x, :y

attr_singleton_reader :x, :y

CREDIT: Trans



13
14
15
16
17
18
# File 'lib/core/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

#attr_singleton_writer(*args) ⇒ Object

Create singleton attr_writers.

obj = Object.new

obj.attr_singleton_writer :x, :y

obj.x = 3
obj.y = 4

CREDIT: Trans



31
32
33
34
35
36
# File 'lib/core/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

#Bit(n) ⇒ Object

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



94
95
96
# File 'lib/core/facets/integer/bitmask.rb', line 94

def Bit(n)
  1 << Integer(n)
end

#blank?Boolean

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?

Returns:

  • (Boolean)


13
14
15
16
# File 'lib/core/facets/kernel/blank.rb', line 13

def blank?
  return empty? if respond_to?(:empty?)
  !self
end

#bool?Boolean

Returns true is an object is class TrueClass or FalseClass, otherwise false.

true.bool?   #=> true
false.bool?  #=> true
nil.bool?    #=> false

Returns:

  • (Boolean)


33
34
35
# File 'lib/core/facets/boolean.rb', line 33

def bool?
  (true == self or false == self)
end

#callstack(level = 1) ⇒ Object Also known as: call_stack

Parse a caller string and break it into its components, returning an array composed of:

  • file (String)

  • lineno (Integer)

  • method (Symbol)

For example, from irb

callstack(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



29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/core/facets/kernel/callstack.rb', line 29

def callstack(level = 1)
  call_str_array = pp_callstack(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

#case?(*matchers) ⇒ Boolean

Returns:

  • (Boolean)


3
4
5
# File 'lib/core/facets/kernel/case.rb', line 3

def case?(*matchers)
  matchers.all?{ |m| m === self }
end

#cli(*args) ⇒ Object (private)

CLI is based on Clap library Copyright © 2010 Michel Martens



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
# File 'lib/standard/facets/cli.rb', line 7

def cli(*args)
  opts = args.pop
  argv = (args.first || ARGV).dup
  args = []

  # Split option aliases.
  opts = opts.inject({}) do |h,(k,v)|
    k.to_s.split(/\s+/).each{|o| h[o]=v}; h
  end

  # Convert single dash flags into multiple flags.
  argv = argv.inject([]) do |a, v|
    if v[0,1] == '-' && v[1,1] != '-'
      a.concat(v[1..-1].chars.map{|c| "-#{c}"})
    else
      a << v
    end
    a
  end

  while argv.any?
    item = argv.shift
    flag = opts[item]

    if flag
      # Work around lambda semantics in 1.8.7.
      arity = [flag.arity, 0].max

      # Raise if there are not enough parameters
      # available for the flag.
      if argv.size < arity
        raise ArgumentError
      end

      # Call the lambda with N items from argv,
      # where N is the lambda's arity.
      flag.call(*argv.shift(arity))
    else

      # Collect the items that don't correspond to
      # flags.
      args << item
    end
  end

  args
end

#completeObject

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



21
22
23
# File 'lib/core/facets/kernel/complete.rb', line 21

def complete
  loop { break unless yield }
end

#d(*x) ⇒ Object

Like #p but gives file and line number…

d("hi")

produces …

"hi" (/home/dave/projects/foo.rb, 38)


11
12
13
14
# File 'lib/core/facets/kernel/d.rb', line 11

def d(*x)
  puts "#{x.inspect} #{caller[0]}"
  return *x
end

#deep_clone(cache = {}) ⇒ Object

Deep clone an object by deep cloning every instance variable as well.

Returns [Object]



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/core/facets/kernel/deep_clone.rb', line 8

def deep_clone(cache={})
  return cache[self] if cache.key?(self)

  copy = clone()
  cache[self] = copy

  copy.instance_variables.each do |var|
    val = instance_variable_get(var)
    begin
      val = val.deep_clone(cache)
    rescue TypeError
      next
    end
    copy.instance_variable_set(var, val)
  end

  return copy
end

#deep_copyObject

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.



9
10
11
# File 'lib/core/facets/kernel/deep_copy.rb', line 9

def deep_copy
  Marshal::load(Marshal::dump(self))
end

#demand(promise) ⇒ Object

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.



218
219
220
221
222
223
224
# File 'lib/core/facets/lazy.rb', line 218

def demand( promise )
  if promise.respond_to? :__result__
    promise.__result__
  else # not really a promise
    promise
  end
end

#demo(out = $stdout, &block) ⇒ Object

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’



25
26
27
# File 'lib/core/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

#disable_warningsObject Also known as: silence_warnings

CREDIT: Trans



6
7
8
9
10
11
# File 'lib/core/facets/kernel/disable_warnings.rb', line 6

def disable_warnings #:yield:
  verbose, $VERBOSE = $VERBOSE, nil
  yield
ensure
  $VERBOSE = verbose
end

#eigenObject



30
31
32
33
# File 'lib/core/facets/kernel/meta.rb', line 30

def eigen
  warn "The `eigen' method is deprecated. Please use `meta' instead."
  meta
end

#eigenclassObject

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’



19
20
21
# File 'lib/core/facets/kernel/eigenclass.rb', line 19

def eigenclass
  (class << self; self; end)
end

#enable_warningsObject

CREDIT: Trans



19
20
21
22
23
24
# File 'lib/core/facets/kernel/disable_warnings.rb', line 19

def enable_warnings #:yield:
  verbose, $VERBOSE = $VERBOSE, true
  yield
ensure
  $VERBOSE = verbose
end

#ergo(&b) ⇒ Object

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 but returns the result.

CREDIT: Daniel DeLorme



18
19
20
21
22
23
24
# File 'lib/core/facets/kernel/ergo.rb', line 18

def ergo(&b)
  if block_given?
    b.arity == 1 ? yield(self) : instance_eval(&b)
  else
    self
  end
end

#extensionObject

Don’t say it!



7
8
9
# File 'lib/core/facets/kernel/extension.rb', line 7

def extension
  class << self; self; end
end

#false?Boolean

Returns true is an object is class FalseClass, otherwise false.

true.false?   #=> false
false.false?  #=> true
nil.false?    #=> false

Returns:

  • (Boolean)


21
22
23
# File 'lib/core/facets/kernel/true.rb', line 21

def false?
  (false == self)
end

#future(&computation) ⇒ Object

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.



233
234
235
# File 'lib/core/facets/lazy.rb', line 233

def future( &computation ) #:yields: result
  Lazy::Future.new(&computation)
end

#hierarchical_send(method_name, *args, &block) ⇒ Object

TODO:

Include singleton class?

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


28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# File 'lib/core/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(&block) ⇒ Object

Hierarchically apply a block, passing each ancestor to the block starting at the root ancestor and working toward the current object.



6
7
8
9
10
# File 'lib/core/facets/class/hierarchically.rb', line 6

def hierarchically(&block)
  ancestors.reverse_each do |m|
    block.call(m)
  end
end

#in?(other) ⇒ Boolean

Is self included in other?

5.in?(0..10)       #=> true
5.in?([0,1,2,3])   #=> false

Returns:

  • (Boolean)


8
9
10
# File 'lib/core/facets/kernel/in.rb', line 8

def in?(other)
  other.include?(self)
end

#instance_assign(hash) ⇒ Object

Set instance variables using a hash.

instance_assign('@a'=>1, '@b'=>2)
@a   #=> 1
@b   #=> 2

NOTE: Conceptually a better alternative to this method is ‘instance.update`

from the `instance` gem. However, practically this method is probably 
the better choice until such time that Ruby supports anonymous delegators.


13
14
15
16
17
18
19
# File 'lib/core/facets/kernel/instance_assign.rb', line 13

def instance_assign(hash)
  hash.each do |k,v|
    k = "@#{k}" if k !~ /^@/
    instance_variable_set(k, v)
  end
  self
end

#instance_class(&block) ⇒ Object

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



20
21
22
23
# File 'lib/core/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

#instance_extract(hash) ⇒ Object

Like ‘instance_assign`, but only assigns an instance variable if it does not already exist.

@a = 9
instance_extract('@a'=>1, '@b'=>2)
@a   #=> 9
@b   #=> 2

CREDIT: T. Yamada



13
14
15
16
17
18
19
# File 'lib/core/facets/kernel/instance_extract.rb', line 13

def instance_extract(hash)
  hash.each do |k,v|
    k = "@#{k}" if k !~ /^@/
    instance_variable_set(k, v) unless instance_variable_defined?(k)
  end
  self
end

#instance_replace(source) ⇒ Object

Replace state of object with the state of another object of the same class (or superclass).

class ReplaceExample
  attr_reader :a, :b
  def initialize(a,b)
    @a, @b = a, b
  end
end

obj1 = ReplaceExample.new(1,2)
obj1.a  #=> 1
obj1.b  #=> 2

obj2 = ReplaceExample.new(3,4)
obj2.a  #=> 3
obj2.b  #=> 4

obj1.instance_replace(obj2)
obj1.a  #=> 3
obj1.b  #=> 4

This is very similar to ‘instance.assign`, but it is limited by the class of object, in the same manner as Array#replace.

NOTE: Conceptually a better alternative is ‘instance.replace` provided

by the `instance` gem. However, practically this method is probably 
the better choice until such time that Ruby support anonymous delegators.

Raises:

  • (ArgumentError)


32
33
34
35
36
37
# File 'lib/core/facets/kernel/instance_replace.rb', line 32

def instance_replace(source)
  raise ArgumentError, "not a #{self.class} -- #{source}" unless source.is_a?(self.class)
  instance_variables.each do |iv|
    instance_variable_set(iv, source.instance_variable_get(iv))
  end
end

#like?(x) ⇒ Boolean Also known as: equate?

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.like?(1.0)               #=> true
"string".like?("string")   #=> true
String.like?("string")     #=> true

Returns:

  • (Boolean)


11
12
13
# File 'lib/core/facets/kernel/like.rb', line 11

def like?(x)
  equal?(x) || eql?(x) || self == x || self === x
end

#load(file, wrap = false) ⇒ Object (private)

Load script and print what is being loaded.



19
20
21
22
# File 'lib/standard/facets/load_monitor.rb', line 19

def load(file, wrap=false)
  $stderr.puts "monitor load: #{file}\n#{caller.inspect}\n\n"
  load_without_monitor(file, wrap)
end

#load_all(pattern, safe = nil) ⇒ Object

Same as #require_all, but for #load.



28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/core/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_relative(relative_feature, safe = nil) ⇒ Object

Load file from same dir as calling script.

load_relative 'myscript'

CREDIT: Paul Brannan, Pragmatic Programmers



11
12
13
14
15
16
17
18
19
20
# File 'lib/core/facets/kernel/load_relative.rb', line 11

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

#load_without_monitorObject



8
# File 'lib/standard/facets/load_monitor.rb', line 8

alias_method :load_without_monitor, :load

#maybe(chance = 0.5, &block) ⇒ Object

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


10
11
12
13
14
15
16
# File 'lib/core/facets/kernel/maybe.rb', line 10

def maybe(chance = 0.5, &block)
  if block
    yield if rand < chance
  else
    rand < chance
  end
end

#memo(*args, &block) ⇒ Object

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’



32
33
34
35
36
37
38
39
40
41
# File 'lib/core/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

#metaObject

Call methods on the eigenclass (i.e. the singleton_class).

name = "Tom"
name.eigen.define_method(:turkey){ self + " Turkey" }
name.turkey #=> "Tom Turkey"

One of the nice things you can do with #eigen is define class attributes without having to open a ‘class << self` block.

c = Class.new do
  meta.attr_accessor :a
end
c.a = 1
c.a #=> 1


22
23
24
25
26
27
28
# File 'lib/core/facets/kernel/meta.rb', line 22

def meta
  Functor.new do |op,*a,&b|
    (class << self; self; end).class_eval do
      __send__(op,*a,&b)
    end
  end
end

#meta_alias(*args) ⇒ Object

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



17
18
19
20
21
# File 'lib/core/facets/kernel/meta_alias.rb', line 17

def meta_alias(*args)
  meta_class do
    alias_method(*args)
  end
end

#meta_class(&block) ⇒ Object Also known as: metaclass

Easy access to an object’s “special” class, otherwise known as it’s singleton class, eigenclass, adhoc class or object-qua-class.



6
7
8
9
10
11
12
# File 'lib/core/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

#meta_def(name, &block) ⇒ Object

Add method to a meta-class –i.e. a singleton method.

class X; end
X.meta_def(:x){"x"}
X.x  #=> "x"

CREDIT: WhyTheLuckyStiff



13
14
15
16
17
# File 'lib/core/facets/kernel/meta_def.rb', line 13

def meta_def( name, &block )
  meta_class do
    define_method( name, &block )
  end
end

#meta_eval(str = nil, *file_and_line, &blk) ⇒ Object

Evaluate code in a metaclass. This is equivalent to:

meta_class.instance_eval(...)

CREDIT: WhyTheLuckyStiff



11
12
13
14
15
16
17
# File 'lib/core/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

#method!(s) ⇒ Object

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"


20
21
22
23
# File 'lib/core/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

#no?(question) ⇒ Boolean

Ask a question expecting a no answer.

Returns:

  • (Boolean)


16
17
18
19
20
21
22
23
# File 'lib/core/facets/kernel/yes.rb', line 16

def no?(question)
  case ask(question).downcase
  when 'n', 'no'
    true
  else
    false
  end
end

#notObject

Inversion functor.

true.not.nil?  #=> true


17
18
19
# File 'lib/core/facets/kernel/not.rb', line 17

def not
  Functor.new(&method(:not_send).to_proc)
end

#not?Boolean

Same as using NOT operator ‘!’.

true.nil?.not? == !true.nil?

Returns:

  • (Boolean)


9
10
11
# File 'lib/core/facets/kernel/not.rb', line 9

def not?
  !self
end

#not_nil?Boolean

The opposite of #nil?.

"hello".not_nil?     # -> true
nil.not_nil?         # -> false

CREDIT: Gavin Sinclair

Returns:

  • (Boolean)


10
11
12
# File 'lib/core/facets/kernel/not_nil.rb', line 10

def not_nil?
  ! nil?
end

#not_send(op, *a, &b) ⇒ Object (private)



32
33
34
# File 'lib/core/facets/kernel/not.rb', line 32

def not_send(op, *a, &b)
  !__send__(op, *a)
end

#nullObject



27
28
29
# File 'lib/standard/facets/nullclass.rb', line 27

def null
  NullClass.new
end

#object_hexidObject

Returns the object id as a string in hexideciaml, which is how Ruby reports them with inspect…

"ABC".object_hexid  #=> "0x402d359c"


24
25
26
# File 'lib/core/facets/kernel/object_hexid.rb', line 24

def object_hexid
  HEXID_TEMPLATE % (__id__ << 1)
end

#p(*x) ⇒ Object

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.



18
19
20
21
# File 'lib/core/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

#presenceObject

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'


38
39
40
# File 'lib/core/facets/kernel/blank.rb', line 38

def presence
  self if present?
end

#present?Boolean

An object is present if it’s not blank.

Returns:

  • (Boolean)


19
20
21
# File 'lib/core/facets/kernel/blank.rb', line 19

def present?
  !blank?
end

#promise(&computation) ⇒ Object

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.



207
208
209
# File 'lib/core/facets/lazy.rb', line 207

def promise( &computation ) #:yields: result
  Lazy::Promise.new(&computation)
end

#qua_class(&block) ⇒ Object Also known as: quaclass

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



20
21
22
23
24
25
26
# File 'lib/core/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

#require(file) ⇒ Object (private)

Require script and print what is being require.



11
12
13
14
# File 'lib/standard/facets/load_monitor.rb', line 11

def require(file)
  $stderr.puts "monitor require: #{file}\n#{caller.inspect}\n\n"
  require_without_monitor(file)
end

#require_all(pattern) ⇒ Object

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.



14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/core/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_without_monitorObject



7
# File 'lib/standard/facets/load_monitor.rb', line 7

alias_method :require_without_monitor, :require

#respond(sym = nil, *args, &blk) ⇒ Object

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

This method was known as #try until Rails defined #try to be something more akin to #ergo.

CREDIT: Chris Wanstrath



23
24
25
26
27
28
29
30
# File 'lib/core/facets/kernel/respond.rb', line 23

def respond(sym=nil, *args, &blk)
  if sym
    return nil if not respond_to?(sym)
    __send__(sym, *args, &blk)
  else
    Functor.new(&method(:respond).to_proc)
  end
end

#returning(obj = self) {|obj| ... } ⇒ Object

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

Yields:

  • (obj)


22
23
24
25
# File 'lib/core/facets/kernel/returning.rb', line 22

def returning(obj=self) #:yield:
  yield obj
  obj
end

#safe_memo(*args, &block) ⇒ Object

Thead-safe instance-level memoization.

class MemoExample
  attr_accessor :a
  def m
    safe_memo{ @a }
  end
end

ex = MemoExample.new

ex.a = 10
ex.m  #=> 10

ex.a = 20
ex.m  #=> 10


36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/standard/facets/thread.rb', line 36

def safe_memo(*args, &block)
  if args.empty?
    args = block.binding.eval('[self, __method__]')
  end
  $MEMO_MUTEX.synchronize do
    if $MEMO.key?(args)
      $MEMO[args]
    else
      $MEMO[args] = block.call
    end
  end
end

#sandbox(rescueblock_or_default = nil) ⇒ Object (private)

CREDIT: Zucker



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/standard/facets/thread.rb', line 79

def sandbox(rescueblock_or_default=nil) #:yield:
  Thread.start do
    $SAFE = 4
    yield
  end.value
rescue SecurityError => e
  if !rescueblock_or_default.nil?
    if rescueblock_or_default.is_a? Proc
      rescueblock_or_default.call e
    else
      rescueblock_or_default
    end
  else
    raise e
  end
end

#send_as(ancestor, sym, *args, &blk) ⇒ Object

Call parent class/module methods once bound to self.

TODO: Does this have the proper scope for #send?



37
38
39
# File 'lib/core/facets/kernel/as.rb', line 37

def send_as(ancestor, sym, *args, &blk)
  ancestor.instance_method(sym).bind(self).call(*args,&blk)
end

#silence(*streams) ⇒ Object

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.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/core/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

#silence_stderrObject

Equivalent to ‘silence_stream(STDERR)`.



63
64
65
# File 'lib/core/facets/kernel/silence.rb', line 63

def silence_stderr #:yeild:
  silence_stream(STDERR) { yield }
end

#silence_stdoutObject

Equivalent to ‘silence_stream(STDOUT)`.



68
69
70
# File 'lib/core/facets/kernel/silence.rb', line 68

def silence_stdout #:yeild:
  silence_stream(STDOUT) { yield }
end

#silence_stream(*streams) ⇒ Object

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



49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/core/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

#silently(*streams) ⇒ Object

Just like silence_stream, but will default to STDOUT, STDERR if no streams are given.



34
35
36
37
# File 'lib/core/facets/kernel/silence.rb', line 34

def silently(*streams) #:yeild:
  streams = [STDOUT, STDERR] if streams.empty?
  silence_stream(*streams){ yield }
end

#singleton_classObject

Easy access to an object’s “special” class.

NOTE: This is already defined in Ruby 1.9+.



6
7
8
# File 'lib/core/facets/kernel/singleton_class.rb', line 6

def singleton_class
  (class << self; self; end)
end

#super_method(klass, meth) ⇒ Object

Returns method of a parent class bound to self.



4
5
6
7
8
9
# File 'lib/core/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

#tapObject

The tap K-Combinator. This yields self -and- returns self.

'foo.yml'.tap{ |f| YAML.load(f) }  #=> 'foo.yml'

Unlike Ruby’s definition, this rendition can be used as a higher order message. This form allows a single call before returning the receiver.

YAML.tap.load_file('foo.yml').load_file('bar.yml')

IMPORTANT: This is one of few core overrides in Facets.



17
18
19
20
21
22
23
24
# File 'lib/core/facets/kernel/tap.rb', line 17

def tap #:yield:
  if block_given?
    yield(self)
    self
  else
    Functor.new{ |op,*a,&b| self.send(op, *a, &b); self }
  end
end

#temporarily(settings) ⇒ Object

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


10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/core/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

#to_bObject

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



17
18
19
# File 'lib/core/facets/boolean.rb', line 17

def to_b
  self ? true : false
end

#to_boolObject

All objects except false and nil are “true”.



22
23
24
# File 'lib/core/facets/boolean.rb', line 22

def to_bool
  true
end

#to_yamlfragObject

As with #to_yaml but removes the header line (i.e. ‘—’) to create a “YAML fragment”.

Author:

  • Trans



22
23
24
25
26
# File 'lib/standard/facets/yaml/kernel.rb', line 22

def to_yamlfrag
  y = to_yaml
  y.sub!(/---\ */, '')
  y
end

#trap_chain(signal_name, *args, &block) ⇒ Object

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’



19
20
21
22
23
24
25
# File 'lib/core/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

#true?Boolean

Returns true is an object is class TrueClass, otherwise false.

true.true?   #=> true
false.true?  #=> false
nil.true?    #=> false

Returns:

  • (Boolean)


10
11
12
# File 'lib/core/facets/kernel/true.rb', line 10

def true?
  (true == self)
end

#try(method = nil, *args, &block) ⇒ Object

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 }


35
36
37
38
39
40
41
# File 'lib/core/facets/kernel/try.rb', line 35

def try(method=nil, *args, &block)
  if method
    __send__(method, *args, &block)
  else
    self
  end
end

#val?Boolean

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

Returns:

  • (Boolean)


12
13
14
15
16
# File 'lib/core/facets/kernel/val.rb', line 12

def val?
  return false if nil?
  return false if empty? if respond_to?(:empty?)
  true
end

#with(obj = self, &block) ⇒ Object

Like returning but exectues the block via instance_eval.

def foo
  with values = [] do
    self << 'bar'
    self << 'baz'
  end
end

foo # => ['bar', 'baz']


15
16
17
# File 'lib/core/facets/kernel/with.rb', line 15

def with(obj=self, &block)
  obj.instance_eval(&block)
end

#writers(*ancestors_and_options) ⇒ Object

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.



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
# File 'lib/core/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

#Y(*args, &block) ⇒ Object

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’



19
20
21
# File 'lib/core/facets/kernel/y.rb', line 19

def Y(*args, &block)
  y = lambda{|*args| block.call(*args, &y) }
end

#yaml(*args, &blk) ⇒ Object

The Kernel method #yaml is a shortcut to YAML::load.

data = yaml %{
  a: 1
  b: 2
}  
data #=> {"a"=>1, "b"=>2}


13
14
15
# File 'lib/standard/facets/yaml/kernel.rb', line 13

def yaml(*args,&blk)
  YAML.load(*args,&blk)
end

#yes?(question) ⇒ Boolean

Ask a question expecting a yes answer.

Returns:

  • (Boolean)


6
7
8
9
10
11
12
13
# File 'lib/core/facets/kernel/yes.rb', line 6

def yes?(question)
  case ask(question).downcase
  when 'y', 'yes'
    true
  else
    false
  end
end