BasicObject provides an abstract base class
with no predefined methods (except for __send__
and
__id__
). BlankSlate is useful as
a base class when writing classes that depend upon
method_missing
(e.g. dynamic proxies).
This is the same as a Binding. Not really needed, but I like consistency :)
for Ruby 1.8 -> 1.9 transition
The Dictionary class is a Hash that preserves order. So it has some array-like extensions also. By defualt a Dictionary object preserves insertion order, but any order can be specified including alphabetical key order.
Just require this file and use Dictionary instead of Hash.
# You can do simply hsh = Dictionary.new hsh['z'] = 1 hsh['a'] = 2 hsh['c'] = 3 p hsh.keys #=> ['z','a','c'] # or using Dictionary[] method hsh = Dictionary['z', 1, 'a', 2, 'c', 3] p hsh.keys #=> ['z','a','c'] # but this don't preserve order hsh = Dictionary['z'=>1, 'a'=>2, 'c'=>3] p hsh.keys #=> ['a','c','z'] # Dictionary has useful extensions: push, pop and unshift p hsh.push('to_end', 15) #=> true, key added p hsh.push('to_end', 30) #=> false, already - nothing happen p hsh.unshift('to_begin', 50) #=> true, key added p hsh.unshift('to_begin', 60) #=> false, already - nothing happen p hsh.keys #=> ["to_begin", "a", "c", "z", "to_end"] p hsh.pop #=> ["to_end", 15], if nothing remains, return nil p hsh.keys #=> ["to_begin", "a", "c", "z"] p hsh.shift #=> ["to_begin", 30], if nothing remains, return nil
You can use order_by to set internal sort order.
#<< takes a two element [k,v] array and inserts.
Use ::auto which creates Dictionay sub-entries as needed.
And ::alpha which creates a new Dictionary sorted by key.
Convenience method for an argument slot. It simple returns the X exception class.
# File lib/more/facets/partial.rb, line 36 def __ X end
# File Rakefile, line 101 def add_loadpath(*paths) live = ENV['live'] unless live # $LOAD_PATH.unshift(File.expand_path('lib/core')) # $LOAD_PATH.unshift(File.expand_path('lib/more')) paths.each do |path| $LOAD_PATH.unshift(File.expand_path(path)) end end puts "RUBY VERSION: #{RUBY_VERSION}" puts "LOAD PATH:\n" + $LOAD_PATH.join("\n") if $DEBUG end
# File lib/core/facets/duplicable.rb, line 5 def clone? ; true ; end
Can you safely call dup on this object? False for nil, false, true, symbols, and numbers; true otherwise.
# File lib/core/facets/duplicable.rb, line 4 def dup? ; true ; end
# File Rakefile, line 116 def get_tests(find=nil) find = find && File.directory?(find) ? File.join(find, '**/test_*.rb') : find find = find || ENV['TESTS'] || 'test/**/test_*.rb' Dir.glob(find) end
Create an inheritor “class attribute”.
Inheritor providse a means to store and inherit data via the class heirarchy. An inheritor creates two methods one named after the key that provides a reader. And one named after key! which provides the writer. (Because of the unique nature of inheritor the reader and writer can't be the same method.)
The first argument is the inheritor's name. The second argument is the archtype object. This object must be duplicable (via dup). The last argument is either the symbolic operator/method or a block that specifies how one hierarchical level “integrates” with the next.
class X inheritor :foo, [], :+ end class Y < X end X.x! << :a X.x => [:a] Y.x => [:a] Y.x! << :b X.x => [:a] Y.x => [:a, :b]
It is interesting to note that the only reason inheritor is needed at all is becuase Ruby does not allow modules to be “inherited” at the class-level, or conversely that the class-level is not a module instead. Otherwise using super at the class-level would suffice.
NOTE: Adding an inheritor directly to Module or Class will probably not do what is expected. Thankfully that usecase is likely a YAGNI, but in anycase it is even more likely that it is not possible with this code.
# File lib/more/facets/inheritor.rb, line 67 def inheritor(key, obj, op=nil, &fop) raise ArgumentError if op && fop if !fop op = op ? op.to_sym : :+ fop = lambda{ |o, x| o.__send__(op, x) } end #(class << self; self; end).module_eval do class_extend do define_method(key) do ancestors.reverse.inject(obj.dup) do |o, a| if a.respond_to?("#{key}!") fop.call(o, a.__send__("#{key}!")) else o end end end define_method("#{key}!") do if instance_variable_defined?("@#{key}") instance_variable_get("@#{key}") else instance_variable_set("@#{key}", obj.dup) end end end end
Access private internals of an object with a fluid notation.
class X attr :a private :a def initialize @a = 1 end end x = X.new p x.instance_eval.a #=> 1 p x.a #=> Error
A useful example might include adding accessors to a metaclass.
class X metaclass.instance_eval.attr :x end
This method is called instance to go along with methods that provide similar access, such as instance_variables and instance_eval. In fact, one could argue this would be a good return value of instance_eval is no block is given.
This method was once called pry and privy.
TODO: Will only support calls with blocks as of Ruby 1.9+.
# File lib/more/facets/instance_eval.rb, line 34 def instance_eval(*args, &block) return super if block or !args.empty? @_instance_eval ||= Functor.new do |op, *a| instance_eval{ send(op, *a) } end end
Evaluate the block with the given arguments within the context of this object, so self is set to the method receiver.
From Mauricio's eigenclass.org/hiki/bounded+space+instance_exec
This version has been borrowed from Rails for compatibility sake.
# File lib/core/facets/kernel/instance_exec.rb, line 16 def instance_exec(*args, &block) begin old_critical, Thread.critical = Thread.critical, true n = 0 n += 1 while respond_to?(method_name = "__instance_exec#{n}") InstanceExecMethods.module_eval { define_method(method_name, &block) } ensure Thread.critical = old_critical end begin send(method_name, *args) ensure InstanceExecMethods.module_eval { remove_method(method_name) } rescue nil end end
SETUP/INSTALL
# File Rakefile, line 188 def load_setup begin require 'setup' $setup_installed = true rescue LoadError $setup_installed = false puts "NOTP" end end
# File lib/more/facets/stash.rb, line 53 def merge!(other) super(other.rekey(&:to_s)) end
This will automatically load (most) core methods if they are not present when called.
# File lib/core/facets-live.rb, line 8 def method_missing(methodname, *a, &b) methodname = OpEsc.escape(methodname) begin require "facets/#{class}/#{methodname}" __send__(methodname, *a, &b) rescue LoadError super end end
# File lib/more/facets/nullclass.rb, line 57 def null? false end
Get or set state of object.
TODO: Would instance_state be a more appropriate name?
# File lib/core/facets/kernel/object_state.rb, line 5 def object_state(data=nil) if data instance_variables.each do |iv| name = iv.to_s.sub(/^[@]/, '').to_sym instance_variable_set(iv, snap[name]) end else data = {} instance_variables.each do |iv| name = iv.to_s.sub(/^[@]/, '').to_sym data[name] = instance_variable_get(iv) end data end end
# File Rakefile, line 134 def prepare_tests_all add_loadpath('lib/core','lib/more') files = get_tests run_tests(files) end
# File Rakefile, line 140 def prepare_tests_core add_loadpath('lib/core') files = get_tests('test/core') run_tests(files) end
# File Rakefile, line 146 def prepare_tests_more add_loadpath('lib/more') files = get_tests('test/more') run_tests(files) end
Replace state of object.
# File lib/core/facets/kernel/object_state.rb, line 22 def replace(data) instance_variables.each do |iv| name = iv.to_s.sub(/^[@]/, '').to_sym instance_variable_set(iv, data[name]) end end
# File Rakefile, line 122 def run_tests(files) files.each do |file| next if File.directory?(file) begin puts "Loading: #{file}" if $DEBUG load(file) rescue LoadError puts "Error loading: #{file}" end end end
# File lib/core/facets/boolean.rb, line 135 def to_bool return true end
# File lib/more/facets/stash.rb, line 49 def update(other) super(other.rekey(&:to_s)) end
# File lib/more/facets/stash.rb, line 61 def values_at(*keys) super(keys.map{|k|k.to_s}) end