DoubleX RMVXA Object Trace
Version: v1.02a
Introduction
* Traces all objects belonging to a queried class linked to a queried object
* Designed as a bug diagnosis tool used by scripters with debug experience
Example
obj.inspect
200 Scripts 30 Scripters Inspect Example 1
obj.trace_obj(Proc); obj.obj_trace[Proc].inspect
200 Scripts 30 Scripters Obj Trace Proc Example 1
Prerequisites
* Basic knowledge of inspecting objects in Ruby
* Some RGSS3 scripting proficiency to fully utilize this script
Script
Code:
#==============================================================================|
# ** Script Info |
#------------------------------------------------------------------------------|
# * Script Name |
# DoubleX RMVXA Object Trace |
#------------------------------------------------------------------------------|
# * Functions |
# Traces all objects meeting some conditions linked to the queried object |
# Designed as a bug diagnosis tool used by scripters with debug experience |
#------------------------------------------------------------------------------|
# * Example |
# obj.inspect |
# - http://pastebin.com/kb1q1Dru |
# obj.trace_obj(Proc); obj.obj_trace[Proc].inspect |
# - http://pastebin.com/PZ4KNbHv |
#------------------------------------------------------------------------------|
# * Terms Of Use |
# You shall keep this script's Script Info part's contents intact |
# You shalln't claim that this script is written by anyone other than |
# DoubleX or his aliases |
# None of the above applies to DoubleX or his aliases |
#------------------------------------------------------------------------------|
# * Prerequisites |
# Abilities: |
# 1. Basic knowledge of inspecting objects in Ruby |
# 2. Some RGSS3 scripting proficiency to fully utilize this script |
#------------------------------------------------------------------------------|
# * Instructions |
# 1. Open the script editor and put this script into an open slot between |
# Materials and Main, save to take effect. |
#------------------------------------------------------------------------------|
# * Links |
# Script Usage 101: |
# 1. forums.rpgmakerweb.com/index.php?/topic/32752-rmvxa-script-usage-101/ |
# 2. rpgmakervxace.net/topic/27475-rmvxa-script-usage-101/ |
# This script: |
# 1. http://pastebin.com/pySjrKvh |
# Mentioned Patreon Supporters: |
# https://www.patreon.com/posts/71738797 |
#------------------------------------------------------------------------------|
# * Author |
# DoubleX |
#------------------------------------------------------------------------------|
# * Changelog |
# v1.02a(GMT 0100 27-10-2015): |
# 1. Lets uers set the conditions and labels for tracing objects |
# v1.01b(GMT 1300 13-7-2015): |
# 1. Fixed not tracing klass linked to klass linked to queried object bug |
# 2. Fixed some Script Call Info and Implementation documentation typos |
# 3. Added more info in Prerequisites and Script Call Info |
# 4. Increased this script's compactness |
# v1.01a(GMT 1300 6-7-2015): |
# 1. Instance methods can be traced as well |
# v1.00b(GMT 0800 1-7-2015): |
# 1. Fixed object having Range and/or Structs not tracing klass properly bug|
# v1.00a(GMT 1200 27-6-2015): |
# 1. 1st version of this script finished |
#==============================================================================|
#==============================================================================|
# ** Script Call Info |
# A path in the object trace will stop if it'd be cyclic |
#------------------------------------------------------------------------------|
# * Object manipulations |
# 1. trace_obj(cond, label) |
# - Traces all objects meeting cond method linked to this object |
# - Labels all traced objects using label method |
# - cond and label are method symbols in Object Trace Condition Method |
# and Object Trace Label Method respectively |
# 2. obj_trace[cond] |
# - Returns all traced objects meeting cond method linked to this object |
# - cond is a method symbol in Object Trace Condition Method |
# 3. (v1.01a+)trace_idef |
# - Traces all instance methods linked to this object |
# 4. (v1.01a+)idef_trace |
# - Returns the trace of all instance methods linked to this object |
#==============================================================================|
($doublex_rmvxa ||= {})[:Obj_Trace] = "v1.02a"
module DoubleX_RMVXA # v1.02a+
module Obj_Trace
#--------------------------------------------------------------------------|
# Object Trace Condition Method |
# - Setups cond used by trace_obj(cond, label) |
#--------------------------------------------------------------------------|
# cond must be the symbol of a method taking the currently traced object as
# the only arguement
# The below examples are added to help you setup your own cond methods
# Checks if the currently traced object belongs to klass
def self.cond_klass(obj)
obj.is_a?(klass)
end # cond_klass
# Add your own cond methods here
#--------------------------------------------------------------------------|
# Object Trace Label Method |
# - Setups label used by trace_obj(cond, label) |
#--------------------------------------------------------------------------|
# label must be the symbol of a method taking the currently traced object as
# the only arguement
# The below examples are added to help you setup your own label methods
# Labels all traced objects using their class symbol
def self.label_klass(obj)
:"#{obj.class}"
end # label_klass
# Add your own label methods here
end # Obj_Trace
end # DoubleX_RMVXA
#==============================================================================|
# ** Script Implementations |
# You need not edit this part as it's about how this script works |
#------------------------------------------------------------------------------|
# * Script Support Info: |
# 1. Prerequisites |
# - Solid understanding of inspecting objects in Ruby |
# - Decent RGSS3 scripting proficiency to fully comprehend this script |
# 2. Method documentation |
# - The 1st part describes why this method's rewritten/aliased for |
# rewritten/aliased methods or what the method does for new methods |
# - The 2nd part describes what the arguments of the method are |
# - The 3rd part informs which version rewritten, aliased or created this|
# method |
# - The 4th part informs whether the method's rewritten or new |
# - The 5th part informs whether the method's a real or potential hotspot|
# - The 6th part describes how this method works for new methods only, |
# and describes the parts added, removed or rewritten for rewritten or |
# aliased methods only |
# Example: |
# #--------------------------------------------------------------------------| |
# # Why rewrite/alias/What this method does | |
# #--------------------------------------------------------------------------| |
# # *argv: What these variables are |
# # &argb: What this block is |
# def def_name(*argv, &argb) # Version X+; Rewrite/New; Hotspot |
# # Added/Removed/Rewritten to do something/How this method works |
# def_name_code |
# # |
# end # def_name |
#------------------------------------------------------------------------------|
class Object # Edit
#----------------------------------------------------------------------------|
# New public instance variables |
#----------------------------------------------------------------------------|
attr_reader :idef_trace # (v1.01a+)The trace of all linked instance methods
attr_reader :obj_trace # The traces of all objects linked to this object
# (v1.01a+)The list of symbols of all instance variables added by this script
OBJ_TRACE_IVAR = [:"@idef_trace", :"@obj_trace"]
def trace_idef # v1.01a+; New
# Stop tracing the object if the object trace path would be cyclic
@idef_trace ? return : @idef_trace = {}
#
trace_instance_idef
return trace_array_idef if is_a?(Array)
return trace_hash_idef if is_a?(Hash)
return trace_range_idef if is_a?(Range)
trace_struct_idef if is_a?(Struct)
end # trace_idef
def trace_instance_idef # v1.01a+; New
(instance_variables - OBJ_TRACE_IVAR).each { |ivar|
traverse_idef_tree(ivar, instance_variable_get(ivar))
}
end # trace_instance_idef
def trace_array_idef # v1.01a+; New
each_with_index { |val, index| traverse_idef_tree(index, val) }
end # trace_array_idef
def trace_hash_idef # v1.01a+; New
each { |key, val| traverse_idef_tree(key, val) }
end # trace_hash_idef
def trace_range_idef # v1.01a+; New
index = -1
each { |val| traverse_idef_tree(index += 1, val) }
end # trace_range_idef
def trace_struct_idef # v1.01a+; New
each_pair { |key, val| traverse_idef_tree(key, val) }
end # trace_struct_idef
#----------------------------------------------------------------------------|
# Label and use all nonempty subtrees to form the original object trace tree|
#----------------------------------------------------------------------------|
# iks: The index/key/symbol of the object trace
# val: The object to be traced
def traverse_idef_tree(iks, val) # v1.01a+; New
# Recursively traverse the object trace tree using Depth First Search
unless (idefs = val.instance_methods).empty?
@idef_trace[iks] = [idefs]
end
val.trace_idef
return if (trace = val.idef_trace).empty?
(@obj_trace[iks] ||= []) << trace
#
end # traverse_idef_tree
# cond: The object trace condition method symbol taking the object as argument
# label: The object trace label method symbol taking the object as argument
def trace_obj(cond, label) # New
# Stop tracing the object if the object trace path would be cyclic
(@obj_trace ||= {})[cond] ? return : @obj_trace[cond] = {}
#
trace_instance_obj(cond, label)
return trace_array_obj(cond, label) if is_a?(Array)
return trace_hash_obj(cond, label) if is_a?(Hash)
return trace_range_obj(cond, label) if is_a?(Range)
trace_struct_obj(cond, label) if is_a?(Struct)
end # trace_obj
# cond: The object trace condition method symbol taking the object as argument
# label: The object trace label method symbol taking the object as argument
def trace_instance_obj(cond, label) # New
(instance_variables - OBJ_TRACE_IVAR).each { |ivar|
trace_all_obj(cond, label, ivar, instance_variable_get(ivar))
}
end # trace_instance_obj
# cond: The object trace condition method symbol taking the object as argument
# label: The object trace label method symbol taking the object as argument
def trace_array_obj(cond, label) # New
each_with_index { |val, index| trace_all_obj(cond, label, index, val) }
end # trace_array_obj
# cond: The object trace condition method symbol taking the object as argument
# label: The object trace label method symbol taking the object as argument
def trace_hash_obj(cond, label) # New
each { |key, val| trace_all_obj(cond, label, key, val) }
end # trace_hash_obj
# cond: The object trace condition method symbol taking the object as argument
# label: The object trace label method symbol taking the object as argument
def trace_range_obj(cond, label) # v1.00b+; New
# Embeds the klass traces of all ranges linking to this object
index = -1
each { |val| trace_all_obj(cond, label, index += 1, val) }
#
end # trace_range_obj
# cond: The object trace condition method symbol taking the object as argument
# label: The object trace label method symbol taking the object as argument
def trace_struct_obj(cond, label) # v1.00b+; New
each_pair { |key, val| trace_all_obj(cond, label, key, val) }
end # trace_struct_obj
#----------------------------------------------------------------------------|
# Label and use all nonempty subtrees to form the original object trace tree|
#----------------------------------------------------------------------------|
# cond: The object trace condition method symbol taking the object as argument
# label: The object trace label method symbol taking the object as argument
# iks: The index/key/symbol of the object trace
# val: The object to be traced
def trace_all_obj(cond, label, iks, val) # v1.01a+; New
# Recursively traverse the object trace tree using Depth First Search
ot = DoubleX_RMVXA::Obj_Trace
@obj_trace[cond][iks] = [ot.send(label, val)] if ot.send(cond, val)
val.trace_obj(cond, label)
return if (trace = val.obj_trace[cond]).empty?
(@obj_trace[cond][iks] ||= []) << trace
#
end # trace_all_obj
end # Object
#------------------------------------------------------------------------------|
#==============================================================================|
Instructions
* Open the script editor and put this script into an open slot between Materials and Main. Save to take effect.
FAQ
* None so far
Credits and Thanks
None
Author's Notes
* None so far
Terms and Conditions
* You shall keep this script's Script Info part's contents intact
* You shalln't claim that this script is written by anyone other than DoubleX or his aliases
* None of the above applies to DoubleX or his aliases
Changelog
v1.02a(GMT 0100 27-10-2015):
1. Lets uers set the conditions and labels for tracing objects
v1.01b(GMT 1300 13-7-2015):
1. Fixed not tracing klass linked to klass linked to queried object bug
2. Fixed some Script Call Info and Implementation documentation typos
3. Added more info in Prerequisites and Script Call Info
4. Increased this script's compactness
v1.01a(GMT 1300 6-7-2015):
1. Instance methods can be traced as well
2. Increased this script's compactness and readability
v1.00b(GMT 0800 1-7-2015):
1. Fixed object having Range and/or Structs not tracing klass properly bug
v1.00a(GMT 1200 27-6-2015):
1. 1st version of this script finished