All Projects → janlelis → object_shadow

janlelis / object_shadow

Licence: MIT license
The Shadow of a Ruby Object lets you See and Manipulate its Instance Variables and Methods

Programming Languages

ruby
36898 projects - #4 most used programming language

Projects that are alternatives of or similar to object shadow

go-interfaces
This repos has lots of Go interface usage and best practice examples
Stars: ✭ 112 (+330.77%)
Mutual labels:  method
blockchain-in-node
This is an afternoon-project, a blockchain built in node, supporting PoW.
Stars: ✭ 20 (-23.08%)
Mutual labels:  chain
do
Simplest way to manage asynchronicity
Stars: ✭ 33 (+26.92%)
Mutual labels:  chain
unicode-lookup
The web's best unicode lookup tool!
Stars: ✭ 49 (+88.46%)
Mutual labels:  lookup
profiler
A tool to trace java method dynamically for android application.
Stars: ✭ 32 (+23.08%)
Mutual labels:  method
geoip-native-lite
Super-fast IP to country lookups for node.js with minimal RAM usage.
Stars: ✭ 15 (-42.31%)
Mutual labels:  lookup
MLChainDemo
链式文件生成器原理分析(一)
Stars: ✭ 18 (-30.77%)
Mutual labels:  chain
cacheable-lookup
A cacheable dns.lookup(…) that respects TTL 🎉
Stars: ✭ 121 (+365.38%)
Mutual labels:  lookup
kirby3-bolt
Kirby 3 Plugin for a fast Page lookup even in big content trees
Stars: ✭ 24 (-7.69%)
Mutual labels:  lookup
DoubleStar
A personalized/enhanced re-creation of the Darkhotel "Double Star" APT exploit chain with a focus on Windows 8.1 and mixed with some of my own techniques
Stars: ✭ 140 (+438.46%)
Mutual labels:  chain
chimera-framework
Simple Language Agnostic Framework for Stand Alone and Distributed Computing
Stars: ✭ 17 (-34.62%)
Mutual labels:  chain
woodpecker
woodpecker http client for Android
Stars: ✭ 17 (-34.62%)
Mutual labels:  chain
fenris
A library for advanced finite element computations in Rust
Stars: ✭ 52 (+100%)
Mutual labels:  method
postcss-property-lookup
PostCSS plugin for property lookups, similar to Stylus
Stars: ✭ 67 (+157.69%)
Mutual labels:  lookup
django-querysetsequence
Chain multiple (disparate) QuerySets in Django
Stars: ✭ 92 (+253.85%)
Mutual labels:  chain
hscode
📘🖥 A command line reference tool for http status codes.
Stars: ✭ 31 (+19.23%)
Mutual labels:  lookup
CutAndDisplace
Boundary Element MATLAB code. Modelling faults and deformation
Stars: ✭ 40 (+53.85%)
Mutual labels:  method
lightflow
A tiny Promise-inspired control flow library for browser and Node.js.
Stars: ✭ 29 (+11.54%)
Mutual labels:  chain
node-dns
🌐 DNS Server and Client Implementation in Pure JavaScript with no dependencies.
Stars: ✭ 390 (+1400%)
Mutual labels:  lookup
IterTools.jl
Common functional iterator patterns
Stars: ✭ 124 (+376.92%)
Mutual labels:  chain

Object#shadow [version] [ci]

Have you ever been confused by some of Ruby's meta-programming methods?

If your answer is Yes, you have come to the right place:

Object and Shadow

With shadow, every Ruby object has a shadow which provides a clean API to access the object's variables and methods.

Never again you will have to do the x.methods - Object.methods trick to get a meaningful method list.

Setup

Add to your Gemfile:

gem "object_shadow"

Usage Example

class P
  def a_public_parent_method
  end
end

class C < P
  def initialize
    @ivar = 42
    @another_variable = 43
  end

  attr_reader :another_variable

  def a_public_method
  end

  protected

  def a_protected_method
  end

  private

  def a_private_method
  end
end

object = C.new

def object.a_public_singleton_method
end

# Get an Overview

require "object_shadow"
object.shadow # ObjectShadow of Object #47023274596520

## Lookup Chain

    #<Class:#<C:0x00005588eb283150>> → C → P → Object → …

## 2 Instance Variables

    [:ivar, :another_variable]

## 4 Public Methods (Non-Class/Object)

    [:a_public_method, :a_public_parent_method, :a_public_singleton_method, :another_variable]

## 1 Protected Method (Non-Class/Object)

    [:a_protected_method]

## 2 Private Methods (Non-Class/Object)

    [:a_private_method, :initialize]

# Read & Manipulate Instance Variables

object.shadow[:ivar] # => 42
object.shadow[:another_variable] = 23; object.another_variable # => 23
object.shadow.variables # => [:ivar, :another_variable]
object.shadow.to_h # => {:ivar=>42, :another_variable=>23}
object.shadow.remove(:ivar) # => 42 (and removed)

# List Available Methods

# shadow features a single method called `methods` which takes some keyword arguments for further listing options
object.shadow.methods # => [:a_public_method, :a_public_parent_method, :a_public_singleton_method, :another_variable]

# Use scope: option to toggle visibility (default is public)
object.shadow.methods(scope: :public) # => [:a_public_method, :a_public_parent_method, :a_public_singleton_method, :another_variable]
object.shadow.methods(scope: :protected) # => [:a_protected_method]
object.shadow.methods(scope: :private) # => [:a_private_method, :initialize]
object.shadow.methods(scope: :all) # => [:a_private_method, :a_protected_method, :a_public_method, :a_public_parent_method, :a_public_singleton_method, :another_variable, :initialize]

# Use inherit: option to allow or prevent traversal of the inheritance chain
object.shadow.methods(scope: :public, inherit: :singleton) # => [:a_public_singleton_method]
object.shadow.methods(scope: :public, inherit: :self) # => [:a_public_method, :a_public_singleton_method, :another_variable]
object.shadow.methods(scope: :public, inherit: :exclude_object) # => [:a_public_method, :a_public_parent_method, :a_public_singleton_method, :another_variable]
object.shadow.methods(scope: :public, inherit: :all) # => [:!, :!=, :!~, :<=>, :==, :===, :=~, :__id__, :__send__, :a_public_method, :a_public_parent_method, :a_public_singleton_method, :another_variable, :class, :clone, :define_singleton_method, :display, :dup, :enum_for, :eql?, :equal?, :extend, :freeze, :frozen?, :hash, :inspect, :instance_eval, :instance_exec, :instance_of?, :instance_variable_defined?, :instance_variable_get, :instance_variable_set, :instance_variables, :is_a?, :itself, :kind_of?, :method, :methods, :nil?, :object_id, :private_methods, :protected_methods, :public_method, :public_methods, :public_send, :remove_instance_variable, :respond_to?, :send, :shadow, :singleton_class, :singleton_method, :singleton_methods, :taint, :tainted?, :tap, :then, :to_enum, :to_s, :trust, :untaint, :untrust, :untrusted?, :yield_self]

# Use target: :instances or :class to jump between child and class method listings
C.shadow.methods == C.new.shadow.methods(target: :class) #=> true
C.shadow.methods(target: :instances) == C.new.shadow.methods #=> true
Enumerable.shadow.methods(target: :instances) # (lists Enumerables' methods)

Documentation

Instance Variables

Shadow exposes instance variables in a Hash-like manner:

Method Description
[] Retrieve instance variables. Takes a symbol without @ to identify variable.
[]= Sets instance variables. Takes a symbol without @ to identify variable.
remove Removes an instance variables. Takes a symbol without @ to identify variable.
variable? Checks if a variable with that name exists. Takes a symbol without @ to identify variable.
variables Returns the list of instance variables as symbols without @.
to_h Returns a hash of instance variable names with @-less variables names as the keys.
to_a Returns an array of all instance variable values.

Method Introspection

All method introspection methods get called on the shadow and take a target: keyword argument, which defaults to :self. It can take one of the following values:

Value of target: Meaning
:self Operate on the current object
:class Operate on the current object's class (the class for instances, the singleton class for classes)
:instances Operate on potential instances created by the object, which is a class (or module)

methods(target: :self, scope: :public, inherit: :exclude_class)

Returns a list of methods available to the object.

Only shows methods matching the given scope:, i.e. when you request all public methods, protected and private methods will not be included. You can also pass in :all to get methods of all scopes.

The inherit: option lets you choose how deep you want to dive into the inheritance chain:

Value of inherit: Meaning
:singleton Show only methods directly defined in the object's singleton class
:self Show singleton methods and methods directly defined in the object's class, but do not traverse the inheritance chain
:exclude_class Stop inheritance chain just before Class or Module. For non-modules it fallbacks to :exclude_object
:exclude_object Stop inheritance chain just before Object
:all Show methods from the whole inheritance chain

method?(method_name, target: :self)

Returns true if such a method can be found, false otherwise

method_scope(method_name, target: :self)

Returns the visibility scope of the method in question, one of :public, :protected, :private. If the method cannot be located, returns nil.

method(method_name, target: :self, unbind: false, all: false)

Returns the Method or UnboundMethod object of the method requested. Use unbind: true to force the return value to be an UnboundMethod object. Will always return UnboundMethods if used in conjunction with target: :instances.

If you pass in all: true, it will return an array of all (unbound) method objects found in the inheritance chain for the given method name.

method_lookup_chain(target: :self, inherit: :exclude_class)

Shows the lookup chain for the target. See methods() for description of the inherit: option.

Q & A

Can I Access Hidden Instance Variables?

Some of Ruby's core classes use @-less instance variables, such as Structs. They cannot be accessed using shadow.

Does It Support Refinements?

Currently not.

Other Meta Programming?

Only some aspects of Ruby meta-programming are covered. However, shadow aims to cover all kinds of meta-programming. Maybe you have an idea about how to integrate eval, method_missing, and friends?

Does this Gem Include a Secret Mode which Activates an Improved Shadow Inspect?

Yes, run the following command.

ObjectShadow.include(ObjectShadow::DeepInspect)
42.shadow

Requires the following gems: paint, wirb, io-console

J-_-L

Copyright (C) 2019-2021 Jan Lelis https://janlelis.com. Released under the MIT license.

PS: This gem would not exist if the instance gem did not come up with the idea.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].