For those not familiar with class#send:
class Rubyist
def welcome(*args)
"Welcome " + args.join(' ')
end
end
obj = Rubyist.new
puts(obj.send(:welcome, "famous", "Rubyists")) # => Welcome famous Rubyists
Since we can already use #responds_to? to do something like:
class Helloworld
def custom_method
puts "hi"
end
end
ex = Helloworld.new
if ex.responds_to?(:custom_method)
# ...
end
The only problem that I currently see, aside from send as a method name that would break a lot of apps out there, is #responds_to? doesn't support Symbol types that aren't explicitly written directly into the parameter as a symbol for example:
class Hello
end
example = Hello.new
# works
if example.responds_to?(:example)
end
stored = {} of String => Symbol
stored["example"] = :example
puts typeof(stored["example"]) # => Symbol
### below will spit out:
### 'Syntax error in eval:9: unexpected token: stored (expected symbol)'
### despite the type being a symbol
# not possible
# if example.responds_to?(stored["example"])
# end
Also @asterite talks about a few faults regarding a #send method such as:
1. You have to include a class/methods table in the executable to be able to search it for runtime execution.
2. Since methods in Crystal are instantiated when you use them, if you don't use a method then it won't appear in the executable.
But that's pretty much solved with #responds_to? so I don't think it's a problem now that the language is much mature aside from the issue I brought up previously w/ passing stored symbol values to the responds_to method not being possible.
With that said, I'd really _love_ this feature added to crystal or some form of class reflection and I could comfortably move over to crystal from php as my main language once we get closer to 1.0.
Since this is already getting down-votes, now I'm curious to why some of you don't want this as a feature?
@exts Because it would be prohibitively difficult (impossible without changing language semantics) to implement, for the exact reason you mention in your issue
Since methods in Crystal are instantiated when you use them, if you don't use a method then it won't appear in the executable.
@exts Is there a current use case that you can't cover with the current language and you need send for it?
@asterite is there a use case that I can't cover w/ the current language that send is required? _no_, it'd just cut down a lot of code to a few lines for reasons that I'd use it for personally, more for convenience purposes.
Adding send will open the door for "I will implement everything with send because I can", making all code in most shards just be fragile and slow. If there isn't a real use case for this other than "less code to write at the cost of slower runtime execution and unexpected behaviour" then chances of us implementing this are basically zero. Add to that the fact that, reasons mentioned above, it would be super hard to implement it, probably impossible.
@asterite alright
@exts FWIW do you have a more specific use case? Maybe we can help you compress it a little or something... ;)
@kirbyfan64 no offense to the core dev on mustafa, but in this example you're kind of forced to write unnecessary boilerplate to accomplish what he's doing here because something like #send doesn't exist in crystal. Another method to accomplish a similar goal is how I'm doing it in my micro-framework.
Here I'm forced to create an 'action' method if I want to have true controllers that aren't single actions which I managed to do here. My original goal was to be able to do exactly what I'm currently doing except I wouldn't need to have an action factory method (i could even create a factory class which refactors this bit out, but it seems unnecessary) to call dynamic routes.
You can look in the readme for an example of the goal I had in mind for my micro-framework.
Regardless, it's impossible to implement within the current code base based on the responses above. I like crystal, but you have to work a little harder to accomplish a few things :)
Most helpful comment
Adding
sendwill open the door for "I will implement everything withsendbecause I can", making all code in most shards just be fragile and slow. If there isn't a real use case for this other than "less code to write at the cost of slower runtime execution and unexpected behaviour" then chances of us implementing this are basically zero. Add to that the fact that, reasons mentioned above, it would be super hard to implement it, probably impossible.