01-12-2011, 01:00 PM
Ruby Extensions
by Mystinar
Jan 12 2011
Below is a bunch of extra functions I've written for the base ruby classes to extend functionality in different ways. Most of these are math related. I don't take credit for all of these. It was a few years ago that I wrote this code, so I don't recall where I got some of it.
One piece of code I'd like to point out is the Integer.sum function, which adds all the numbers from 1..X without iteration. This code is useful for generating a character's experience point table. For example, if you wanted experience points to progress at the same rate as in Dungeons and Dragons, you would use:
actor.level.sum * 1000
To use these scripts, just create a new script in the script editor (preferably placed above Game_Temp) and paste the code below into it:
by Mystinar
Jan 12 2011
This is a locked, single-post thread from Creation Asylum. Archived here to prevent its loss.
No support is given. If you are the owner of the thread, please contact administration.
No support is given. If you are the owner of the thread, please contact administration.
Below is a bunch of extra functions I've written for the base ruby classes to extend functionality in different ways. Most of these are math related. I don't take credit for all of these. It was a few years ago that I wrote this code, so I don't recall where I got some of it.
One piece of code I'd like to point out is the Integer.sum function, which adds all the numbers from 1..X without iteration. This code is useful for generating a character's experience point table. For example, if you wanted experience points to progress at the same rate as in Dungeons and Dragons, you would use:
actor.level.sum * 1000
To use these scripts, just create a new script in the script editor (preferably placed above Game_Temp) and paste the code below into it:
Extensions.rb
Code:
#! /usr/bin/env ruby
#This file contains extensions to some of the base classes and modules in Ruby.
#
#<b>Modules Extended:</b> Enumerable, Kernel
#
#<b>Classes Extended:</b> Array, Float, Integer, Numeric, Object, Range, String
#Extensions to the Enumerable module
module Enumerable
#Returns the amount of elements which return *true* for the given block.
def amount(&block)
n = 0
each {|i| n += 1 if yield i}
return n
end
alias :total :amount
alias :count :amount
#Returns *true* if all? returns *false* with the given block.
def none?(&block)
return all? {|i| yield i} == false
end
alias :xall? :none?
#Returns *true* if any? returns *false* with the given block.
def some?(&block)
return any? {|i| yield i} == false
end
alias :xany? :some?
alias :has? :include?
end
#Extensions to the Array class.
class Array
#Returns the average value of every numeric element in an array.
def mean
a = 0.0
self.each {|i| a + i if i.is_a?(Numeric)}
return a / self.size
end
alias :avg :mean
#Converts self to a hash. The index and objects in the array are essentially flipped in their purpose. For example, if some_array[3] == "string", then in the hash it would read as some_hash["string"] == 3.
def to_hash
hash = {}
self.each_with_index {|v,i| hash[v] = i}
return hash
end
#Returns a random index from self.
def random
return fetch(rand(size))
end
end
#Extensions to the Float class.
class Float
#Returns the numbers past the decimal point.
def dclip
return self - self.to_i
end
#Returns self rounded to the nth decimal point, as specified in *num*.
def to_dec(num)
return (self * (10.0 ** num)).round / (10.0 ** num)
end
end
#Extensions for the Integer class.
class Integer
#Adds up all the numbers within one..self without the use of recursion or looping.
def sum
return ((self+1) * (self / 2.0)).to_i
end
#Returns true if self is an even number.
def even?
return (self % 2 == 0)
end
#Returns true if self is an odd number.
def odd?
return (self % 2 != 0)
end
end
#Extensions to the Numeric class.
class Numeric
def within?(rng)
return (self >= rng.first and self <= rng.final)
end
def within?(min, max)
return (self >= min and self <= max)
end
#Checks if self is within the range specified in *r*, and then returning the results (correcting the value if necesary). Alternatively, one can set the upper and lower values as seperate arguments.
# Example 1:: 10.limit(9..11) = 10
# Example 2:: 12.limit(9..11) = 11
# Example 3:: 8.limit(0, 11) = 8
# Example 4:: 11.limit(9...11) = 10
def limit(*r)
if r.size == 1
a, b = r[0].first, r[0].final
elsif r.size == 2
a, b = r[0], r[1]
else
raise ArgumentError, "wrong number of arguments (" + r.size.to_s + " for 1 or 2)"
end
c = (self < a ? a : self)
return (c < b ? c : b)
end
#Returns the amount of digits within self.
def digits
return Math.log10(self.abs).floor + 1
end
#Returns self, rounded to the *d* digit place.
# Example:: 12345.d_round(2) = 12300
def clip(d)
return (self / (10.0**d)).round * (10**d)
end
#Returns self, rounded to the last *d* digits.
# Example:: 12345.hd_round(2) = 12000
def nclip(d)
return self.clip(self.digits - d)
end
#Returns self as string with comma-separated thousands.
#<tt>method found at Rubygarden[http://wiki.rubygarden.org/Ruby/page/show/FixNumFormat] </tt>
def commify
splitter = Regexp.compile "(\\d{#{3}})"
before, after = self.to_s.split('.')
before = before.reverse.gsub splitter, '\1' + ','
str = "#{ before.chomp( ',' ).reverse }"
str += ".#{ after }" if after
return str
end
end
#Extensions for the Object class.
class Object
#Returns true if self is not an instance of <b>klass</b>.
def not_a?(klass)
return self.is_a?(klass) == false
end
end
#Extensions for the Range class.
class Range
#Returns the real last number of self.
#Example 1:: (1..10).final = 10
#Example 2:: (1...10).final = 9
def final
return exclude_end? ? last-1 : last
end
#Returns the sum of all values within self, using Integer#sum.
def sum
return final.sum - (first-1).sum
end
#Returns the real size of self.
#Example 1:: (1..10).length = 10
#Example 2:: (1...10).length = 10
#Example 3:: (3..10).length = 7
def length
return final - first + 1
end
#Returns a random number from within self.
def random
return rand(length) + first
end
#Adds together the values of a range
def +(val)
a, b = self.min, self.max
if val.is_a?(Range)
a += val.min
b += val.max
elsif val.is_a?(Integer)
a += val
b += val
elsif val.is_a?(Float)
a += val.to_i
b += val.to_i
else
raise "Only Ranges, Integers, or Floats may be added to a range"
end
if self.exclude_end?
self.initialize(a...b)
else
self.initialize(a..b)
end
end
end
#Extensions to the String class.
class String
#Returns an amount of characters from the start of self, specified by *num*.
def left(num=1)
return self[0...num]
end
#Returns *true* if the first characters in self are equal to *str*.
def left_is?(str)
return self.left(str.size) == str
end
#Deletes the first *num* characters from self, returning the characters removed.
def xleft(num)
str = self.left(num)
self[0...num] = ''
return str
end
#Returns self, excluding the last *num* characters.
def nlast(num=1)
return self[0...(length-num)]
end
#Returns an amount of characters from the end of self, specified by *num*.
def right(num=1)
return self[length-num,num]
end
#Returns true if the last characters equal *str*.
def right_is?(str)
return self.right(str.size) == str
end
#Deletes the last *num* characters from self, returning the characters removed.
def xright(num)
str = self.right(num)
self[(length-num)...length] = ''
return str
end
#Returns self, excluding the first *num* characters.
def nfirst(num=1)
return self[num...length]
end
#Returns *b* amount of characters, starting with character *a*.
def mid(a=0, b=1)
return self[a,b]
end
#Returns self with the string specified in *str* inserted in front of it.
def prepend(str)
return str + self
end
#Inserts the string specified in *str* in front of self.
def prepend!(str)
self.insert(0,str)
end
#Returns self, with the string specified in *str* added on to it.
def append(str)
return self + str
end
alias :append! :concat
#Returns self as a numeric value
def to_n
a, b = self.to_f, self.to_i
return a == b ? b : a
end
#Returns all characters before first instance of *str*.
def before(str)
return self[0...index(str)]
end
#Returns all characters after last instance of *str*.
def after(str)
return self[(rindex(str)-1)...length]
end
end