4 ms·
It's verbose, but it's not a mess. It's quite coherent actually. For smaller encounters, there are a number of procedural reflection functions available. For th
by troels 16y ago
It's verbose, but it's not a mess. It's quite coherent actually. For smaller encounters, there are a number of procedural reflection functions available. For this case, you could do:
get_class_methods('A');
- andrewvc 16y agoverbosity creates messes.
- eru 16y agoPerhaps. Though it would certainly be nicer, if A was a first-class citizen in PHP, and you would not have to pass its name around as a string.
- roel_v 16y agoWhat if the name of A is only known at runtime? Referencing function and class names and if need be, also variable names, as string is very transparent to me. It also maps nicely to how it's implemented underneath - everything is stored and accessed in hashes.
- eru 16y agoThe name of A doesn't matter. Look at how e.g. Python solves this: class A: pass class B: pass a = A() b = B() # only known at run-time: c = random.choice([a,b]) print c.__class__ No mucking around with names needed. The same applies to functions---like PHP's array_map function which takes the name of the callback as an argument, instead of the function itself. I also don't understand why PHP's syntax treats variables whose type is a function different than variables which have a more mundane type. I.e. nearly all variables need prefixing with a $, but variables which hold a function need no such thing. And you can not assign to those function-variables.
- roel_v 16y agoSo now you want to instantiate a variable of type "A", where "A" is a string that you read in from a configuration file. How do you do it in Python? (I guess it's possible somehow, I'm just wondering what the syntactic advantages are). Your second sentence I don't understand - what do you mean 'variables whose type is a function'? The equivalent of a function pointer? For variable functions, you take a regular variable (i.e., with a $) and assign it the name of the function you want to call: function call_me($arg) {} $func = 'call_me'; $func(1);
- eru 16y ago> So now you want to instantiate a variable of type "A", where "A" is a string that you read in from a configuration file. How do you do it in Python? Depends on which kind of flexibility you want. You can use a dict of name to type i.e. d = {"A":A, "B":B} variable = d[string_from_file] (arguments) or (perhaps slightly un-Pythonic, I guess) variable = getattr(my_types_module, string_from_file) (arguments) where my_types_module is a module with your constructors. The second version is somewhat closer to the PHP version, but still cleaner. The problem with a system like function call_me($arg) {} $func = 'call_me'; $func(1); is that it does not play well if you have several different functions of the same name but in different scopes. Or if you want to generate functions on the fly. That's a concern, but not too much of a concern in a language like Python. I only chose Python because many people are somewhat familiar with it, and it does the Right Thing in this regard. As an aside: Matlab recently changed from a PHP-like functions-passed-around-by-string-name system to functions-as-first-class-citizens system. They even had to introduce a new bit of syntax for that---but they found it important enough to go through with it. (Look at http://stackoverflow.com/questions/796935/function-handle-in-matlab http://stackoverflow.com/questions/796935/function-handle-in... if you want to read about it.)
- roel_v 16y ago"variable = getattr(my_types_module, string_from_file) (arguments)" Right, and how is that more readable or more clear than the PHP equivalent? $myclass = new $classname; vs variable = getattr(my_types_module, string_from_file) (arguments) and you claim the second is cleaner? Furthermore you are making several normative claims like 'Right Thing' but don't offer anything to back that opinion up. Function pointers are strongly typed too, does that make them superior? No just different, and I think the PHP way fits perfectly well with a consistent theme: you can substitute any name that you'd hard-code with a variable and it will work. $var = 'test'; // Call function called 'test' with argument value of 'test'; $var($var); // Set variable called '$test' to a new instance of class 'test'. $$var = new $var; // Call method 'test' on variable '$test' with argument 'test'. $test->{$test}($var); Straightforward and no need for strange 'getattr' indirection functions (see how I turned an in itself neutral design decision into a normative statement there?)
- troels 16y agoSure, but that has little to do with the reflection api. PHP is unique among its class of languages (counting Ruby, Python, Perl etc.) in that it has an extremely dynamic runtime, but yet keeps the compiletime/runtime distinction known from compiled languages, such as Java. I have a love/hate relationship to that. On one hand it feels stupid and restrictive compared to more thought-out languages such as Scheme, Javascript or ruby, but on the other hand it _does_ instil some stability in an environment that is quite chaotic in other respects (dynamic-weak typing has some confusing edge cases, just to name one). I'm not sure it's such a bad balance after all.
- eru 16y ago> but yet keeps the compiletime/runtime distinction Could you elaborate on that? I don't see what you mean. Interestingly, Python usually also gets compiled---though the target language (Python's byte code) is still very dynamic.
- troels 16y agoI meant semantically, not literally. PHP has a class based object model that is basically copied from Java. One of the more absurd results of this transplantation is that in PHP, classes can implement static interfaces. This is useful in Java, to imbue some flexibility into the otherwise very rigid static typing, but in PHP it's utterly backwards. As an aside, PHP gets compiled into opcode before interpretation, but the two processes are usually not separated. This is true for most interpreted languages actually.