Last active
March 9, 2024 18:00
-
-
Save veelenga/91fb751286b35f1b497f1a1c41228c06 to your computer and use it in GitHub Desktop.
Implementation of send method in Crystal using macros and procs. Just a proof of concept.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Object | |
macro inherited | |
@@methods = {} of String => Proc({{@type}}, Nil) | |
macro method_added(method) | |
\{% if method.visibility == :public %} | |
%key = \{{ method.name.stringify }} | |
@@methods[%key] = ->(obj : \{{@type}}) { | |
obj.\{{ method.name }}() | |
nil | |
} | |
\{% end %} | |
end | |
protected def self.proc(obj, name) | |
@@methods[name]?.try &.call(obj) | |
end | |
end | |
def send(method_name) | |
{{@type}}.proc(self, method_name.to_s) | |
end | |
end | |
class Foo | |
def foo | |
puts "Foo!" | |
end | |
def bar | |
puts "Bar!" | |
end | |
def baz | |
puts "Baz!" | |
end | |
end | |
foo = Foo.new | |
[:foo, :bar, :baz].each { |m| foo.send m } | |
# Foo! | |
# Bar! | |
# Baz! | |
# foo.send ARGV[0] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is a dummy alternative of send method. Keep in mind, it is inefficient and violates Crystal best practices. Does not allow you to pass arguments, does not work with method overloading and could have other limitations.
Made for fun ;)
How it works
It uses
method_added
to fill the hash with procs that call methods.send
method just retrieves required proc from the hash and makes a call.