-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] respond_to? for library functions #1688
Comments
This would probably not be feasible before integration with https://github.com/manastech/crystal_lib is done. |
I'm not so sure about that. The logic is pretty simple and can be implemented as compiler directives. Pseudo code to run during compilation.
|
@technorama what about usage of static libraries, which cannot be |
I think this can be devided into two separate features: A) Determining if a linked library includes a specific symbol. This can be achieved using macros - which should be easier and more flexible solution than introducing new keyword like For example something like this: lib LibFoo
{% if symbol_defined?(:foo) %}
fun foo
{% end %}
end For shared libraries this should be relatively easy to do using the already existing bindings to B) Make if LibFoo.responds_to?(:foo)
LibFoo.foo
end This nearly works, but currently it is required to assign the type to a variable: libfoo = LibFoo
if libfoo.responds_to?(:foo)
libfoo.foo
end An alternative would be to provide a macro method for this purpose. There is already crystal/src/crystal/system/unix/time.cr Lines 39 to 43 in d7273c7
But: I don't think that actually works. {% if !LibC.methods.includes?("printf".id) %}
LibC.printf("foo") # => foo
{% end %} |
Might be related to #5244 |
If someone's interested, I tried a stab at implementing the macro method in this branch. A few notes on that:
|
@straight-shoota I have a working thing using {% if SomeLib.has_function? "some_fun" %}
# do stuff
{% end %} I plan to make a PR in the next few days to discuss my implementation tentative, but feel free to play with it ;) |
Hi, what is going on with this addition? |
This already works, but only inside methods (not at the top-level): lib LibFoo
fun foo
fun bar(x : Int32) : Int32
end
def foo
{{ LibFoo.class.methods.stringify }}
end
p foo Just do |
Hmm, I tried something like this, however I'm always getting false no matter what name I pass into it: lib LibFoo
fun version = version : Int32
end
macro exists?(name)
{{ LibFoo.class.methods.any? { |m| m.name == name.id } }}
end
p exists?("version") # Always false, IDK why |
@Heaven31415 As I said, it only works when you use it inside a method, not at the top-level... |
Sorry, I just didn't get it first time, now I see, thanks for help. |
Many libraries have functions that may or may not exist depending on version, configure options, or platform. Optional functions allow additional features/methods to be used depending on the specifics of the library installed. Querying for the availability of a function can be done using
dlopen
anddlsym
.Suggested syntax:
With
Or
Please note the above can be evaluated at compile time and no runtime conditionals are necessary.
The text was updated successfully, but these errors were encountered: