From: Paul Prescod Date: 2001-08-12T09:37:10+09:00 Subject: [ruby-talk:19560] Re: order and freedom in Ruby (was: Re: Re: the way class variables work) Chris Uzdavinis wrote: > >... > > I'm talking about behavior and type MUTATION. Let's say you have a library with code you do not have the implementation for. What if it has buried within it code that totally changes its behaviour on every Monday, Friday and Saturday. Isn't that dynamic behaviour changing? Would you care whether it was implemented by means of an "if" statement and a call time time() or through dynamic method changing and "eval"? In C I could set up a list of a thousand function pointers and in my "statically compiled" function, all I do is take in the arguments and call one of these pointers based on the time of day. In fact you can use dynamic loading to make C or C++ just as dynamic as Ruby, if you are perverse enough. You can also overwrite vtable pointers in C++ on some platforms. >... > Your question is a diversion. I'm not asking how to force an errones > call to succeed. I'm asking how, given a function (whose behavior may > change from one call to the next) I can determine what needs to be > passed in in order to produce a valid call. The function's behaviour will only change if someone changes it. Either you trust the implementor of the libraries you load or you do not. If they change the method at runtime it will be for a good reason and to a method with a similar signature. If you don't trust them, you shouldn't load their code into your program. >... > Ruby's dynamic method mutation capabilities, means that all bets are > off. I could be calling completely different functions from one > invocation to the next, it can have changing requirements. Heck, it > can have requirements that are unique every time the program is run. Just like in C. >... > Huh? NULL is a value, not a type. NULL is a value in some languages but in type theory it is usually considered a type onto itself. After all, it can stand in for any other type so it isn't a value of any of those types in the traditional sense. >.. > It's an idea. Considering that Ruby programs are capable of > dynamically changing, I'm just thinking about dynamic adaptions to > that change. I think it's interesting to think about. Okay, I won't bother you if you are just engaging in some mind-experiments. But what you said was: "I am still trying to figure out how one can write non-trivial applications in Ruby, since the interfaces can dynamically change, and you can't find out until runtime if your code has type-errors." In most applications, trivial or non-trivial, the chance of an interface dynamically changing is essentially 0. So this feature has no impact on the ability to write non-trivial apps. > Also, you seem to be convinced that testing is sufficient. Unless > your tests show 100% coverage of every line of every file that your > Ruby program uses, you don't know if one of those untested lines may > change your environemnt and break your code. Further, even 100% > coverage doesn't really mean much, since it could be a series of > calls, or only particular values of certain function calls, which > trigger the kinds of change that can be destructive. Just like in C. Testing doesn't guarantee you don't have bugs. It guarantees that you catch all of the obvious bugs. > Finally, I'm thinking about a call to eval, which opens up the world > to unknown code. (I know about safe-levels of ruby, and tainted > objects, but that's a band aid, not a real solution.) If you don't like eval, just don't use it! Eval is no different than dynamic module loading (dl_open) in C. Dynamic loading is also dangerous if you don't trust the provider of the code you are loading. So don't use it. > There is no amount of testing that can prove correctness over > dynamically changing problems. No amount of testing can (in general) prove correctness in ANY programming language. That's a consequence of Turing completeness. C is demonstrably harder to test than Ruby because in C a malicious hacker can use a buffer overflow to write code into memory and then "eval" that code. This has actually happened pretty often in the real-world whereas your concern about Ruby does not seem to have any real-world consequences. -- Take a recipe. Leave a recipe. Python Cookbook! http://www.ActiveState.com/pythoncookbook