Does Ruby provide any way of obtaining an argument passed to a function as a string literal?
In other words, if I have the following function...
def my_func(arg)
...
end
And I call my_func(obj.prop), I want to be able to obtain the following literal from within my_func...
"obj.prop"
I know Ruby can do some pretty funky things with metaprogramming, but I haven't found a way to be able to do this just yet.
This is not possible.
Ruby is a strict language, meaning that arguments get evaluated before being passed. IOW, all information about how the argument was produced is lost even before the method starts to execute.
There is no way to access the Ruby source code of a particular method, expression, or any other piece of code. In fact, since all Ruby implementations make it trivially easy to integrate with other languages (native extensions and FFI in YARV, mruby, and Rubinius, any JVM language in JRuby, ECMAScript in Opal, any CLI language in IronRuby, native extensions and Smalltalk in MagLev, and so on), there may not even be Ruby source code for a particular piece of code.
You want to obtain a string literal. Literals are part of a language's syntax, they don't even exist at runtime. Not only don't they exist at runtime, the very ideas of "runtime" and "literal" are fundamentally incompatible. Your request is not only impossible, it is non-sensical. There is no possible language, not even a hypothetical one, no possible world, in which your question would even make sense, let alone made to work.
Related
I have an nspire calculator and after writing a hash table implementation, found the BASIC environment to be a pretty offensive programming environment. Unfortunately, as far as I'm aware, it's impossible to use Lua to write libraries.
I did see that somewhere in the Lua interface you can detect variable changes so it might be possible within a file to use Lua functions, but I fear it will go out of scope if used externally.
Is there a better way to do this?
It's not impossible to write Lua libraries for a TI-Nspire. You can put the libraries code into a string, store it as a variable in TI-Basic and put the file in the MyLibs folder. Then, when you want to load your library, do loadstring(var.recall("libfilename/programstring"))(). This will load the library's code as a string from that files, compile it (using loadstring), and execute it (practicaly the same as require).
Also, about getting from controlling a Lua script using TI-Basic, depending on what you want to do, you could use math.eval("<some TI-Basic code>"). This will execute the code in TI-Basic, and return the result as a Lua value (or string). This way, you can call a TI-Basic function every once in a while, and act according to its output.
HHVM 3.9 is not such a fan of ternary statements with named functions, even when passed through fun(), but ≥3.10 is totally fine with them. It seems as though this is one of few cases, however, because 3.9 does accept named functions returned from concrete functions, as well as accepting named functions passed into other functions (3v4l):
<?hh
echo ((() ==> fun('strlen'))())('Hello'); // 5
echo (($f, $v) ==> $f($v))(strlen, 'Hello'); // 5 + Notice: Use of undefined constant strlen - assumed 'strlen'
echo (true ? strlen : intval)('100'); // Fatal error: syntax error, unexpected '(', expecting ',' or ';' on line 3
What changed between 3.9 and 3.10? Are there any cases in HHVM ≥3.10 where named functions cannot be referenced and used this way?
First, when writing Hack, don't write your code at toplevel; the hh_client typechecker can't check anything at toplevel. And 3v4l doesn't run the typechecker at all, you need to run it locally.
That said, no, Hack doesn't really have first-class functions. Most of its behaviour here it inherited from PHP, which also doesn't have them. Back when I was working on the Hack team, we tossed around a lot of ideas for adding them to the language; it's an obvious addition and need. But the need was never quite strong enough such that we sat down and actually worked out the details for both the type system and runtime implications; in particular, how to work out some of the scoping issues that the current callables have. Anonymous functions fill out enough of the need, especially with Hack's short lambda syntax, that there was always something more pressing to deal with.
So Hack just has PHP's normal callable forms; fun is one of a few special functions which give information to the typechecker that the string you specified actually represents a function so the typechecker can do proper type analysis. But at the end of the day, fun just boils down to the usual PHP callable forms with a bit of extra magic in the typechecker.
As to the behaviour you indicate in your 3v4l link. Using strlen and intval like that would cause a type error in Hack, since those are syntactically constants but constants with those names don't exist since Hack doesn't have first-class functions -- or it would if the code weren't at toplevel and you were running the typechecker. As to why it causes a parse error in HHVM 3.9 (which masks the "invalid constant" errors you see in 3.10), I'm not 100% sure. Judging from this example which works in PHP7 and HHVM 3.10, but not PHP5 and HHVM 3.9, my guess it is a PHP7 feature that is backwards compatible and so is always enabled in HHVM.
I am trying to learn a bit about Vala and wanted to create a Calculator to test how Gtk worked. The problem is that I coded everything around the supposition that there would be a way to parse a string that contained the required operations. Something like this:
string operation = "5+2/3*4"
I have done this with Python and it is as simple as using the compilers parser. I understand Python is math oriented, but I thought that perhaps there would be Vala library waiting for me as an answer... I haven't found it if it does exist, but as I was looking at the string documentation, I noticed this part:
/* Strings prefixed with '#' are string templates. They can evaluate
* embedded variables and expressions prefixed with '$'.
* Since Vala 0.7.8.
*/
string name = "Dave";
println (#"Good morning, $name!");
println (#"4 + 3 = $(4 + 3)");
So... I thought that maybe there was a way to make it work that way, maybe something like this:
stdout.printf(#"$(operation)")
I understand that this is not an accurate supposition as it will just substitute the variable and require a further step to actually evaluate it.
Right now the two main doubts I am having are: a) Is there a library function capable of doing this? and b) Is it possible to work out a solution using string templates?
Here's something I found that would do the work. I used the C++ libmatheval library, for this I first required a vapi file to bind it to Vala. Which I found here. There are a lot of available vapi files under the project named vala-extra-apis, and they are recognized in GNOME's Vala List of Bindings although they are not included at install.
You could parse the expression using libvala (which is part of the compiler).
The compiler creates a CodeContext and runs the Vala parser over a (or several) .vala file(s).
You could then create your own CodeVisitor decendant class that visits the necessary nodes of the parse tree and evaluates expressions.
As far as I can see there is no expression evaluator that does this, yet. That is because normally vala code is translated to C code and the C compiler then does compile time expression evaluation or the finished executable does the run time evaluation.
Python is different, because it is primarily a scripting language and has evaluation build directly into the runtime / interpreter.
I find Erlang's module arity import /n where n is the number of arguments rather bizarre.
In Java and various other languages you can do something like:
import static com.stuff.Blah.myFunction;
Which will import all overloaded Blay.myFunction(..) regardless of parameters.
Besides I guess being explicit why did the language designers decide this was a good idea (I'm not trying to criticize the language... just curious)?
Does it have to do with code swapping?
Or does it have to do with hiding guard methods for recursion? If so why not allow arity on export but no need for arity on import?
Why would I want to be that explicit? That is import the two argument function but not the the three argument of myFunction?
You should be aware of what importing functions in Erlang really does. It is a pure textual transformation. If I do an -import(foo, [bar/1,baz/2]). it means that when I write a call like bar(5) or baz(a, 3) the compiler transforms these to foo:bar(5) and foo:baz(a, 3). That is all it does, nothing else. It doesn't check anything:
It doesn't check if the module foo contains the functions bar/1 or baz/2.
It doesn't even check if the module foo exists.
Really all it does is hide that you are calling a function in another module. That is why the recommendation from experienced Erlangers is "don't use it". It was a mistake. Unfortunately it is much easier to add stupid things than to get rid of them so we were never able to remove it.
"Does it have to do with code swapping?"
Yes, sort of. The unit of all code handling in Erlang is the module. So you compile modules, load modules, purge and delete modules. This means that there are no inter-module dependencies at all in the system and the compiler makes no assumptions about other modules when it is compiling a module. No assumptions are made that the environment in which a module is compiled will be the same in which it is run. That is why it is at runtime the system checks whether the function you are trying to call in another exists, or even if the module itself exists. That is why the import was a purely textual transformation.
Erlang was originally developed in Prolog.
In Prolog, the arity adds additional meaning to what you consider to be the 'arguments, as I understand from a function' in a procedural programming language. But that model does not apply here.
The so-called clauses 'married(X,Y).' and 'married(X,Y,Z).' imply a different kind of relationship 'married', which can be declared as married/2 and married/3.
In procedural programming, 'add(a,b)' or 'add(a,b,c)' are intended to generate the addition of a different number of arguments. That's not immediately the case in Prolog, where it is possible to have the relationship 'a and b, added' or 'a, b and c, added' mean something else. Needless to say, Prolog allows you to declare 'add' as you would expect a function would do. But it allows for more. More available meaning, means more need to control it.
And as in any module system, selecting what you want to expose to external clients makes sense: hence the declaration of arity.
Does it have to do with code swapping?
Kind of. The modules in Erlang are compiled separately (which is part of what allows code swapping), unlike Java classes, so the compiler doesn't know how many versions of the imported function with different arities exist. It could assume that all calls of a function with the given name come from the same module, of course, but the designers likely decided it wasn't particularly useful.
In fact, you rarely want to use imports at all, at least in my experience, just as you rarely use static imports in Java. Just write module:function, like Class.staticMethod.
Or does it have to do with hiding guard methods for recursion?
No, since not importing functions doesn't hide them in any way.
My delphi application runs scripts using JvInterpreter (from the Jedi project).
A feature I use is runtime evaluation of expressions.
Script Example:
[...]
ShowMessage(X_SomeName);
[...]
JvInterpreter doesn't know X_SomeName.
When X_SomeName's value is required the scripter calls its OnGetValue-callback.
This points to a function I handle. There I lookup X_SomeName's value and return it.
Then JvInterpreter calls ShowMessage with the value I provided.
Now I consider switching to DelphiWebScript since it has a proper debug-interface and should also be faster than JvInterpreter.
Problem: I didn't find any obvious way to implement what JvInterpreter does with its OnGetValue/OnSetValue functions, though.
X_SomeName should be considered (and actually is, most of the time) a variable which is handled by the host application.
Any Ideas?
Thanks!
You can do that through the language extension mechanism, which has a FindUnknownName method that allows to register symbols on the spot.
It is used in the asm lib module demo, and you can also check the new "AutoExternalValues" test case in ULanguageExtensionTests, which should be closer to what you're after.