Personal taste! May be I am fond of wired taste !!
Sorry for trying to share my wired taste with you.
well, we need to know first before using something.
If you are going to use #true?, you need to know what it does.
I am saying this, for your reply about work with others.
We really don't have Object#true? in ruby. If you see #true? in my code,
you got to look around my code to see what it does?
Same way, If I work with you, you might have some new
opinion/idea/concept that I am not familiar with. In that case, I will
have to do the same.
Mohammad
# rcr.rb
# Ruby Change Requests. Define changes to standard classes.
#
# 04/05/10, JHR, created from earlier work
# 04/05/11, JHR, class Binding methods + Proc##binding()
# 04/06/13, JHR, Binding.of_caller(), thanks to Florian Gross.
#
# (C) See at the end
# What you get when converting an Hash into an Array, see Hash##to_a().
# It is an array of [k,v].
class HashAsArray < Array
def to_h()
h = Hash.new()
each do |(k,v)| h[k] = v end
h
end
end
# What you get when converting an Array into a Hash, see Array##to_h()
# It is a Hash with keys that are integer indexes (from 0 up to size of hash).
class ArrayAsHash < Hash
def to_a()
super().sort_by { |(k,v)| k }.collect { |(k,v)| v }
# ToDo: There must be a faster solution to do that.
end
end
# Have Hash.to_a() return an HashAsArray instead of an Array.
# Besides the class there are no other difference.
class Hash
alias ruby_to_a to_a unless defined? ruby_to_a
# Returns an array of [key,value] pairs.
# Please note that h.to_a().to_h() == h for most purposes.
def to_a()
HashAsArray.new().replace( ruby_to_a())
end
# Returns self. Much like Array##to_a() does.
def to_h()
self
end
# Returns a new Hash updated with members from the other hash.
def +( other )
self.dup().update( other)
end
# Returns a new Hash updated with members from the other hash.
def |( other )
self.dup().update( other)
end
end
# Have Array.to_h() return an ArrayAsHash.
# Please note that aa.to_h().to_a() == aa, which was the initial intend.
class Array
def to_h()
h = ArrayAsHash.new()
each_index do |ii| h[ii] = self[ii] end
return h
end
end
class Symbol
# I often interchange Strings and Symbol in my code.
def intern()
self
end
end
class Continuation
# Thanks to Florian Gross in ruby-talk ML msg 103312.
def self.create( *args, &block )
cc = nil;
result = callcc { |c|
cc = c;
block.call( cc) if block and args.empty?
}
result ||= args
return *[cc, *result]
end
end
# By default class Binding has no methods at all !
class Binding
# Evaluate a Ruby source code string in the binding context.
def eval( str )
Kernel.eval( str, self)
end
# Returns the value of self in the binding context.
def self()
eval( "self")
end
# Returns the local variables defined in the binding context.
def local_variables()
eval( "local_variables")
end
# Returns the Method that was active, if any, when the binding was created
#def method() ...???...
# Returns the Proc that was active, if any, when the binding was created
#def proc() ... ??? ...
# Returns the call stack, same format as Kernel##caller()
def caller( skip = 0 )
eval( "caller( #{skip})")
end
# Returns the value of some variable.
def []( x )
eval( x.to_s())
end
# Set the value of some lvalue.
def []=( l, v )
eval( "proc {|v| #{l} = v").call( v)
end
# Returns the nature of something, nil if that thing is not defined.
def defined?( x )
eval( "defined? #{x}")
end
# Thanks to Florian Gross in ruby-talk ML msg 103312.
# This method returns the binding of the method that called your
# method. Don't use it when you're not inside a method.
#
# It's used like this:
# def inc_counter
# Binding.of_caller do |binding|
# eval("counter += 1", binding)
# end
# end
# counter = 0
# 2.times { inc_counter }
# counter # => 2
#
# You will have to put the whole rest of your method into the
# block that you pass into this method. If you don't do this
# an Exception will be raised. Because of the way that this is
# implemented it has to be done this way.
def self.of_caller( &block )
old_critical = Thread.critical
Thread.critical = true
count = 0
cc, result, error = Continuation.create( nil, nil)
error.call if error
tracer = lambda do |*args|
type, context = args[0], args[4]
if type == "return"
count += 1
# First this method and then calling one will return --
# the trace event of the second event gets the context
# of the method which called the method that called this
# method.
if count == 2
# It would be nice if we could restore the trace_func
# that was set before we swapped in our own one, but
# this is impossible without overloading set_trace_func
# in current Ruby.
set_trace_func( nil)
cc.call( eval( "binding", context), nil)
end
elsif type != "line"
set_trace_func(nil)
error_msg = "Binding.of_caller used in non-method context or " +
"trailing statements of method using it aren't in the block."
cc.call( nil, lambda { raise( ArgumentError, error_msg ) })
end
end
unless result
set_trace_func( tracer)
return nil
else
Thread.critical = old_critical
yield result
end
end
end
class Proc
# Partial evaluation in Ruby. Return a new proc that invokes This
# proc with some of the first parameters pre-initialized.
# Sheme language inspired I think.
# Thanks to Mauricio Fernández
def curry( proc, *args )
prod do | *a |
proc.call( *(args + a))
end
end
# lvalue able
def []=( *args )
self[*args]
end
# Return the proc's binding
def binding()
eval( "binding", self)
end
end
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is The Rever Reversible Reason.
#
# The Initial Developer of the Original Code is
# Jean-Hugues ROBERT (born dec 25 1965 in Nimes, France).
# Portions created by the Initial Developer are Copyright (C) 2002-2004
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
#
# ***** END LICENSE BLOCK *****