I've been pairing with ruby / rails developers since 2010 and coming from statically typed languages, it's unbelievable how much time gets spent playing "guess the method name". Even in rich IDEs like RubyMine, the utter lack of context in any given file in rails leaves programmers typing their best guess of a method name, running the tests, rinse, repeat.
This solution, while creative and laudable, solves a problem that shouldn't exist. It should either be solved by IDE/tooling in a dynamically typed language or by the compiler in a statically typed language. Stop guessing and let your tools do the hard work of remembering method names for you.
I stick a 'binding.pry' (pry gem) in the body of the method I'm trying to write, and I trigger it with a test that has all the correct parameters (i.e. the happy path).
I then write my code in the REPL. I can use 'ls' to look up available methods dynamically. Complex ActiveRecord queries are much easier to prototype. Finding the right method isn't usually too difficult. And pry supports prefix completion at the first level. Assign the result to a variable, and you can do more completion at the next level.
For loops and if-branches, I typically take the bit of data that is relevant to the loop body or that if branch, and work with it separately, to develop that branch. But it's more usual for me to use map and select than explicit loops in any case.
I copy each finished line of code from the repl into my editor, as and when I'm happy with it.
This method of working is also why I don't see any benefit from using RubyMine. I use emacs, and primarily I rely on global project regex (using helm-git-grep and helm-projectile) to navigate the system.
(A happy coincidence is that the default readline key bindings are emacs style, so a lot of what you learn in emacs maps straight over to the repl terminal.)
I actually follow a very similar pattern when developing in both Ruby and Clojure. I particularly like it in Clojure because I can run `(doc function-name)` to get some documentation on the function I intend to use (I can never remember the order of arguments!!).
I do this a lot in the ipython REPL. You can type "method_name?" and see the docstring and some other basic info about the method (like args), its extremely helpful.
It's a hard problem to solve. In general inferring which methods are valid on any given variable or expression is undecidable. So you have to make an approximation, which is hard and the end results usually still disappointing. Here's a little test case:
def foo(x): return x
a = foo("hello")
b = foo(34)
To infer the methods that you can call on `a` and `b` you have to trace through the `foo` function. You can't just run `foo` because what if the input is unknown or what if `foo` contains a loop or is recursive?
def foo(x, i):
if i == 0: return x
else: return foo(x, i-1)
i = int(read_input())
a = foo("hello",i)
b = foo(34,i)
It gets even worse when you have a huge codebase, monkey patching, eval, and other features like that (which Rails uses in copious amounts).
> In general inferring which methods are valid on any given variable or expression is undecidable.
And yet, Hindley-Milner can do it. In general.
I've been working with dynamic and nontyped and weak typed and duck typed languages for over half of my life and you know what, it's getting ridiculous. They were never meant to support the team and project sizes we're forcing them into now.
Hindley-Milner and other type systems do it by restricting the class of programs you are allowed to write. Essentially what they do is if they can't infer the type of a variable they terminate with an error. The class of programs that you are allowed to write is still reasonably big and Turing complete, but as research to make the type system more expressive shows, people want to go beyond that (higher kinds, GADTs, dependent types, polymorphic variants / structural records, subtyping, etc.). Type inference for a dynamically typed language can't terminate with an error if it can't infer the type, it has to be conservative in the other direction: if it can't infer the type of a variable it must assume that it can be anything.
Of course you understand this, but for the benefit of the audience:
HM can do this because it dramatically restricts the allowable complexity of every single name in the program. This is rarely a problem, though, as typically you, as a programmer, only ever intend for names in the program to be so complex. The result is that HM simply ensures that your program is one which makes enough sense all of the time.
Which is sometimes painful for people when they first start.
I also work that way. I use the autoreload feature of ipython so that any code I change in my editor is instantly replicated in my ipython objects. I've really never been more productive in development in my life.
Contrast with some Java I was doing recently (granted, without a Java IDE) and I found the whole cycle painfully slow. Even things the compiler picked up were a magnitude slower to find than when I was in ipython. And then there were plenty of things the compiler wouldn't get, which could take a good minute for me to discover from the time I made the edit. It's insane to me that people don't work in a REPL.
This was your problem. Programming Java without an IDE that recompiles your changes on the fly is just so arcane and really slows you down as you noticed.
Which is great, but that's almost not the main issue. In the ipython REPL I can work with my code and data at the same time. It's a huge disadvantage to not be be able to probe your data to create a working process.
The Java VM has hot code swapping builtin (IIRC limited to method bodies but the commercial JRebel drops that limitation).
Start your program in your IDE's debugger (or point it to your application server where your program is running) and you can change the code immediately, rerun your methods, change variables, inspect the objects, etc.
It's more than a simple REPL, it's a full-blown debugger and it comes really close to what you have in a SmallTalk image where your code, data, and environment is all the same.
Sure. I'm not near my machine for a couple of days but I'll post something when I get the chance. I see your contact info is in your profile so will ping an email when done.
I do something similar with JavaScript and code functions in a REPL and then move the code into my actual file as soon as I get it working. Usually I do this with Google Dev tools console.
It's kind of silly, the major benefit of using Ruby (or JavaScript nowadays) is to iterate quickly. But then, some of their users spend months turning a text editor into an IDE just to waste precious hours on spelling errors.
For example I use pabbrev mode in emacs, which learns what I type. It hints me away from most misspellings because it suggests the correct alternatives before I type them. Most of the long method and variable names for me are a prefix plus a TAB.
I have exactly this frustration as a person coming from static languages (mostly C++) to web dev. Anybody can recommend something more comfortable? I like the concept of Vaadin, but I'd prefer something non-Java.
I'm personally very happy with golang. We are a python shop with some bit of Java on the backend and we decided to try golang to get past a few python performance hurdles. So I wrote a smallish API/data importer as a first application. The results have been fantastic. Nearly as productive as python, better in my opinion support for a functional paradigm, much faster, and of course really easy and great concurrency support. Sure python and django have a good bit more tooling and third party libs but go is gaining ground. One major hurtle I faced was the lack of a good visual debugging IDE. I'm using the go plugin for Intellij but it's not really that good. If go keeps gaining popularity and Intellij releases first class support, like they have with python ruby and node, it will really help the language ecosystem.
Scala is a wonderful language for web dev, particularly if you've found a JVM library you like (the interop is very good). The conciseness and readability (if you stick to the right libraries) of Python with the safety and IDE support of Java. (Can't speak to Vaadin, I'm a big Wicket fan myself)
Er, you mean to say "compiles to machine code." There is no such thing as concurrent machine code... Now the Go language has some fantastic data structures baked-into the syntax that provide a language with which to construct concurrent programs.
Go has some potential (I'm still waiting for Gen/censored/ics :)). Also, I'm particularly interested in components based web frameworks, and there seems to be none so far - last time I found GWT like library for Go, but it is undeveloped/dead I think.
ASP.NET maybe? C# is one of the best-designed languages suitable to server-side dev in modern popular use. Using it with VS is the most convenient and efficient IDE experience I've encountered.
I actually enjoyed WebForms ~10 years ago. But for personal SaaS projects, free/cheap hosting space seems somewhat unrepresented. And I really don't want to go Mono-way...
As for ASP.NET itself - nowadays it seems ASP.NET MVC is recommended, but I find it way too bloat.
Seriously. Is there a good list of tools that provide it? In Python, the only one I've managed to love is PyDev. Supposedly Atom does it with the "script" package?
I've been working with PyCharm [1] a lot lately and I've come to like it a lot. Probably the best context awareness I've seen for any dynamic language - it (almost) feels like working in something more tool-friendly like Java in that regard.
Really?
I used Aptana, which includes the Pydev plugin. I notice everyone seems to give PyCharm lots of love, and have been tempted to try it. Autocomplete is one of the features I rely on heavily.
Jedi is really good. There are plugins for Vim (of course) too.
Personally I believe that things like Jedi - external static code analysers in form of a library - are what we should be doing. It's not good for IDE writers - it lessens vendor lock-in - but for the users it's a win. Having the same, very good, completions in both Vim and Emacs made my life much simpler.
I use Intellij with the PyDev plugin as my IDE and Atom (with the script package) as my text editor. In general unless it's a really quick edit PyDev is MUCH better in the general IDE functions, like autocomplete, jump to definitions, visual breakpoint debugging, etc.. I love atom but Intellij is much better for serious dev/debugging sessions.
I really REALLY dislike eclipse. In fact it would nearly always be my last choice for and ide. In my experience it's slow, buggy, bloated, and in general the features that I need work FAR better in Intellij, Visual Studio, Atom, Sublime Text 2, Emacs, or VIM. I've used pretty much all of them and I would rather go back to them than use an eclipse based project.
It's not a problem that can be solved for a language like ruby without adding type hinting (and probably interfaces) to the language. FWIW php actually does support this.
You don't need (static) type hinting, you can do the same with running a dynamic environment and querying it. That's how it's done in Smalltalk (see Pharo), some Lisps and so on.
You could guess, but it wouldn't work in cases where, for example methods are added to a class dynamically and non deterministically as a side effect of some other operation.
Do you know how "image based" environments work? In short you live in the same space as your code, so when you write some new method you have access to all the "dynamically and non deterministically" code artifacts. With Smalltalk the code is always being run and you get many useful tools for querying the state of a running system. I know it's hard to believe, but you can get much better completion (not to mention refactoring support) with this approach than you get from static analysis.
Which becomes ironic because you end up writing way more text into the file for phpdoc then you would have if it were a static language to begin with; and you end up treating the variables as static type anyway! :|
RubyMine is pretty damn good, especially because you can immediately jump to the source code, even of libraries, and just read the list of available methods. It's amazing to me how completely Dwarf Fortress -- um, I mean vim and tmux -- has conquered the Ruby dev world.
The tool (Ruby) does the hard work: foo.methods. Writing some code, running the tests, rinse, repeat. That describes the REPL way of doing things. Also, the way I prefer to code. Do something, examine the results, do something else.
I personally also find ruby to have uniquely poor naming - lots of similar methods with overlapping functionality, no consistent style, etc.
That's not to say it's a bad language per se, but as someone who works in lots of different languages, I find ruby to be the one where I'm most likely to fail to guess correctly and have to spend time looking up the method I want.
Since it was written by a Japanese fellow originally i think that's where the unique names came from. Upcase and downcase were two that stuck out to me. Overall I like ruby quite a bit though.
This is honestly an issue I don't experience, if I have a typo my test fails and the compiler tells me the line and method call that failed. I correct it, carry on. I can't think of a scenario where you would get stuck with this type of problem.
Compare this with an IDE highlighting this immediately when you write the offending line. In your workflow you have to run a test to identify this issue, then go back and fix it. It certainly doesn't leave you stuck but you are incurring additional overhead in that you actually have to run tests to discover there's a problem and then remediate it.
It's a marginal overhead and it also has the benefit of encouraging clear naming. Autocomplete is convenient but also removes some of the cost of poor naming. This is fine when you're writing code (the autocomplete just kicks in and you search for a method that seems about right) but it does nothing for the readability of your code.
I would argue that readability and writability of class members are not the same. Many time verbosity will improve the readability but hurt the writability of the code, and auto-complete reduce the cost of this verbosity.
A lot of people are recommending IDE-like tooling--but in truly dynamic language (one with a "living image" with path-dependent monkey-patched behavior that can't be replicated during static analysis, like Smalltalk--or, sometimes, Ruby) there's a more idiomatic way.
In a dynamic language, if you're at all unsure of what code you need to write, then you don't write it in your editor in the first place. Instead, you build the expression you need, interactively, at the REPL—and then, once it works, you paste that into your editor.
In dynamic languages, the "dead" code in modules is effectively a coagulation of previously "live" REPL incantations; to trust code that was written "dead" to work correctly "live" is madness (or just a recipe for really long iterations involving unit tests.)
If you take this approach far enough, though, you do get a sort of IDE—something that manages your expression experiments and the context harnesses they need, and re-runs experiments when you edit their dependent formulae. I am, of course, talking about "notebook" interfaces like IPython's.
And with Ruby, especially since you mention Smalltalk, we have a tool that is getting closer to the kind of live introspection and modification that Smalltalk is famous for: Pry [1].
Pry lets you call "binding.pry" anywhere in your program to dump you into a shell within that context, with full access to local variables etc.. And tab-completion and plenty of introspection features. I frequently find myself triggering Pry in the middle of handling http requests if something doesn't work, for example. Letting me inspect the environment, modify stuff, and when I exit the request is completed.
It can also do things (with some limitations) like bring up an editor to where the current method was defined, and let you edit and reload the code.
And you can attach to it remotely using Drb in case the app in question doesn't run attached to a terminal.
At this point it's almost criminal to do Ruby development without Pry.
I second Pry. It's amazing how fast you can use AR to add a little add-hoc business logic on-top of a DB and then drop a console with Pry to get a sort of custom interactive command line DSL :)
TBH if I was writing anything large enough for this kind of stuff to get out of hand, I would seriously consider a statically typed language like Golang or C#/F#(which both have absolutely fantastic tooling). REPL's don't help the next person to come along figure out what your methods are taking in and what those calls return. But I digress.
I don't always cut Ruby, but when I do I cut it with Pry... Yeah.
In pry is it possible to return something when I exit the REPL? Like this:
def do_something
return binding.pry
do_something_but_does_not_work
end
result = do_something
process result
It might be very convenient if I put 'return binging.pry' just before the broken code. I can interactively fix the broken code and continue run outside of current method.
If you are explicit: "return" in a Pry session will exit pry and return the value you pass to it, just as if you are in the method itself. So e.g. "return 42" would return 42 from do_something.
Pry changed my life for Rails development. Before it I was still using IRB and attempting to just log things to the terminal constantly to figure out what I could do. Pry has made me 2x as fast (if not more) as a Ruby developer.
It works great if either A. The IDE lives inside the same live image the project being developed is loaded in; or B. there exists some sort of network/RPC-exposed "code server" running within the live image, which you can ask to do these sorts of completions.
Of non-Smalltalk languages, the only one I can think of with anything like that is Erlang. You could easily enough build a code server in Ruby, but you'd have to explicitly include the library that implements it in your project, and start up a server thread to expose it to an IDE that wanted to talk to it, etc. And because of that, it wouldn't be "part of the language" to the point where tooling (like IDEs) would be built to expect it.
The real problem, though, is that people are coding in dynamic languages with no live image connected to the editing session at all: instead, the code is just dead text until they want to test it, at which point it gets injected into a fresh session, run once, and then the session is immediately discarded (creating what is possibly a completely different path-dependent monkey-patch execution sequence than would happen in production, or in a REPL, or...).
For some languages this happens out of necessity, but for most, it's just an artifact of the batch-processing mentality. All e.g. Light Table gives you, when you think about it, is a text editor with a connection to a live Clojure or Python image; and yet to many it seems to be a completely foreign interaction paradigm for programming.
> You could easily enough build a code server in Ruby, but you'd have to explicitly include the library that implements it in your project, and start up a server thread to expose it to an IDE that wanted to talk to it, etc.
Yeah, I can't help but think we've reinvented the wheel. Modern dynamic languages like Ruby, Python, JS, Clojure, are just now catching up to the state-of-the-art that Smalltalk achieved in the 1980s.
Is it possible that when you try and recreate your image from scratch, the code you have pasted into your editor is not sufficient to recreate the image?
Maybe you pasted some things in the wrong order, or maybe you redefined a function, but some data that was created using the old version of the function is still in the image.
If this is possible in your programming environment, then maybe the dead code is not worth keeping around, and we should only retain the live image.
In which case we need tools to version and diff and branch a live image.
Does a programming environment like that exist I wonder? Or do image based environments like Smalltalk let you export an image as text, like a DB can dump all the SQL required to recreate it?
The creators of Smalltalk encountered the difficulties you're thinking about while they were using Smalltalk for different projects at Xerox PARC in the '70s -- and addressed them.
Simple Smalltalk implementations are in 4 parts: the Smalltalk VM, the Smalltalk image file, the sources file and the changes file.
The image contains compiled code and objects, the sources file contains source code for some of the compiled code in the image (at least the source code provided by the vendor), and the changes file contains a log of changes made using the IDE.
Re-doing the changes recorded in the changes file should be sufficient to recreate the image up-to the last change.
In the late '80s multi person configuration management systems were developed for Smalltalk, see --
Yes. Smalltalk environments export an image that's a snapshot of the entire state of the VM. It's like a reloadable core dump of the VM. It's a binary though, not plaintext. But there is also a sophisticated distributed versioning system for Smalltalk code, which can save versioned snapshots of slices of your code and state that can be imported into different images: http://wiresong.ca/monticello/
No: tests don't change, especially iteratively. If you're editing and re-running your tests in a loop (rather than editing and re-running the code in a loop against the tests), then your tests aren't doing anything related to "testing", because you're changing their pass/fail criteria with each edit. To do so is just to abuse a test suite+test runner as a REPL.
On the other hand, once you know what you're doing, the expectation can be codified into a test (dead code) to assert that the live code maintains an equivalent property with no regressions. A "finished" IPython notebook can indeed be replaced with a regression test to ensure the behavior remains the way you previously determined it to be via experiment. (Though note that this is subtly different from functional testing: you're not asserting any preconceived notion of how an API "should" respond; you're just asserting that the API seems to hold to a certain contract—the one you discovered from your experimentation—and that it's a regression if it then goes against any of the parts of the discovered contract that you had come to rely upon.)
Obviously this is a useful tool, and all the power to the author for finding what looks to be an excellent solution, but this line bothers me:
>>> Sometimes I wasted hours and hours just because there is one character difference. I hate it.
This shouldn't happen. Ever. This should not be a problem anymore. These are the sort of errors that we can catch immediately and should be caught immediately. From looking at the author's GitHub profile, it looks like he uses Emacs, presumably without a plugin that would give him IDE like features. I'm not going to tell him to go use a regular IDE, but it frustrates me that's we can't have those sort of tools available everywhere. (As a vim user myself I have high hopes for the neovim project and look forward to the day when it can be embedded inside a general sort of IDE.)
While you can catch some of these, for a language like Ruby, it's an incredibly hard problem to catch all of these errors immediately because the methods that can be called on a given named entity can not in the general case be known by statically inspecting the source, and you can not in general safely instantiate the application because even class definitions are executed and can have side effects, and the methods available can even vary based on environmental factors, such as whether or not you get a database connection, and what's in the database.
Consider that it is a common pattern for Ruby ORM's to either use method_missing or dynamically define methods to correspond to the current (at connection time) set of columns present in your database.
And "thanks" to the ability to monkey patch and redefining methods, even determining if something "obviously" safe like 42.to_s is not.
There's no way for your editor to handle that unless you stand up a version of your app with an instrumented language environment and lets the editor poke around. Now that is possible with tools like Pry, etc., but it takes a lot more work to do safely (because your editor can't know if it can safely start your app).
Yuki works at Pivotal Labs in NYC. I work there too.
We use whatever editor or IDE any given pair decides to use. In my day-to-day work I've used RubyMine (very popular in our west coast offices), Vim (popular in NYC), Emacs (popular with Mike Dalessio) and my own personal favourite, Sublime Text.
I don't think solutions have to be either/or. Yuki's approach is simple and will cover lots of cases.
You're invoking "IDE" features like it's a panacea. In reality IDEs have only a few limited ways to catch these kinds of errors. With a statically-typed language it can run static analysis at intervals and make sure that all the messages being passed are actually defined on the objects they're being passed to. You can do this precisely because that's what static types gives you.
In dynamic languages you can't do this because you don't know the type that any given identifier is pointing to. The type could be completely arbitrary, I.E. coming from external input. You might think, "oh, well you could just check against all possible methods", and you'd be right, except for Ruby. Ruby allows you to override what happens when you call an undefined method, (method_missing) letting you execute completely arbitrary code that lets undefined methods look just like methods. You could call car.start_and_drive_to_the_bank, and set up the Car type so that it can handle methods like that, (perhaps calling car.start, and then car.drive(bank)) along with .start_and_drive_to_the_mall and whatever. In practice that's bad Ruby, but you still have to be able to handle that, Bad Ruby is still Valid Ruby.
So there's just no way to tell in Ruby whether any given method call is correct or not.
I have an idea to conventionalize method_missing overrides so that they're easier to analyze. Maybe define a regular expression on the class so that the analyzer can sort out what's likely to work at runtime and which messages aren't. Not sure how well it would work until Matz manages to implement static typing as he wants to do in the future. Until you can tell whether any given identifier is likely to be of a type that overrides method_missing, you'd be running the method_missing analyzer for all types on all method calls.
Yeah, but not so you'd notice, coming from an ML or Haskell background. /sarcasm
More seriously, Java and C++ (and C and Algol before them) fell into the trap of defining "data size specifications" as types: The discontinuity between "long long int" and "int" is one, as is the discontinuity between "float" and "double".
The real type difference is between things which are semantically different, like "numeric value used to represent age in years, rounded to integral value", "numeric value used to represent age in days, rounded to integral value", and "numeric value used to represent weight in pounds, rounded to nearest hundredth". Foogol (Algol-derived) languages largely only got this when they embraced Smalltalk-style OO, and they kept their size specification pseudo-types, just to muddy the issue.
Size specifications are useful when defining a wire protocol where the overhead of reading and writing an ASCII format with non-trivial syntax would kill your application, such that you need network-header style bits-on-the-wire protocol, and in file formats with similar constraints, but they're ultimately a low-level implementation detail.
The way this interacts with tooling like editor autocomplete is that editors can do more for you when they know what kind of data you're passing around, as opposed to just how big it is and other trivialities.
C (note lack of quotes) and Haskell regularly trade off "Fastest language in the world" spots on shootouts. Maybe "C" (with quotes), which is obviously a different language, is faster; I doubt it.
Ruby has a linters, but this sort of problem is hard to solve with a linter in a dynamically typed language. It's even harder in a Rails environment since Rails adds many methods to your classes at run time.
Yeah, since it's a dynamically typed lang with inheritance and late binding, doesn't performing static analysis on Ruby code to determine whether a method is defined or not, basically require a solution to the halting problem?
I'm under the impression that you have to actually execute Ruby code to find out with certainty where the methods it calls are defined.
You can solve the "90%" problem statically. My Ruby-compiler-in-progress warns of methods that have not been seen, and I may eventually add some (entirely optional) pragma to allow hinting to reduce false positives (though getting that non-intrusive will be a fun challenge).
But you are right, the general case does require a solution to the halting problem, something which is trivial to demonstrate very explicitly:
eval(STDIN.gets)
42.will_i_halt?
Put that in a file, and run it. Press enter, and it halts. Or cut and paste something like this, and it doesn't:
class Fixnum; def will_i_halt?; loop {}; end; end
And consider that even "require" is a practical equivalent to "eval", so trying to look for eval() calls and similar constructs and think you're safe doesn't work, unless you have a guarantee that the interpreter load paths will be the same when the code is run as what you think it'll be.
But in more pragmatic terms, this is a real issue because many Ruby ORMs for example will add methods that depends on the current state of the databases they connect to, so many typical Ruby applications will actually validly use method names that are not explicitly defined anywhere.
Such things are usually solved by parsing the structured javadoc-like API documentation for classes and methods in addition to the code itself. At least that's how it's done in the PHP world and it works quite well. Obviously it's not going to cover 100% of the cases, but much better than nothing.
Plus it incentivizes you to write this documentation in the first place, which you can then instantly bring up inside the IDE from any place where the method is used.
Blows my mind that IDEs and environments are not better at this. This is something that computers are good at, pattern recognition and scanning the whole file. Of course the it wouldn't work every time, an could make ridiculous suggestions, but I would love the computer to suggest something every time there is an issue. Even if it is wrong 90% of the time, if those guesses don't slow down the programmer the time saved would be huge.
Java IDEs are better at this. JavaScript...well I saw NetBeans do it once and was amazed. Ruby...well it's impossible to do correctly as other posters have mentioned.
The trick is to actually use it. If you auto complete then your coding should be typing 2-3 characters, hit enter, 2-3 characters, enter and so on. It should feel like you're entering hotkeys not typing.
Only real typing should be defining variables and methods.
Your coding speed can go way up depending on how good the autocomplete is.
> Sometimes I wasted hours and hours just becaue there is one charactor difference. I hate it.
Haha, humans are much more able to parse meaning, despite a character being off here or there. Well, you've taken computers one step closer to humans. And you've made programming with Ruby friendlier. Great job!
I see you used the Levenshtein algorithm to calculate the suggestions, very cool idea. I've noticed lately that it is being used quite more often than in the past. (may just be my perception)
Not sure how helpful this is, when it says there's no method called xyz, it's pretty obvious you called the wrong method, or you called it on the wrong thing. Your first thing should be checking that you didn't call the wrong method name.. which involves looking at the error which repeats the method name that you tried to call, and the object you called it on.
Bizarre that this is a genuine hang-up for people.
Could I also highly recommend making your project Rubocop-clean, and using pronto to run Rubocop on your CI server and make comments on your commits in Github. Rubocop warns against any methods you define that are not used at least once.
I would love it if instead of quitting my program with an error, it just went ahead and called the method it thinks I'm referring to. This would remove a lot of unneeded friction from web development.
One of the early PL/1 compilers IBM wrote in the 60's did something akin to this. It was a 'premium' feature, available in one of the more expensive compilers. Where it detected any error or wrong looking code, it would correct it. There's a story floating around somewhere on the net of one guy trying to use it... (Which I can't find at the moment.)
The first time he tried to compile with it, he used a program of roughly "Hello from PL/1". When he ran it, he got a division by zero error, because his string had been turned into an arithmetic expression. With the 1 turned into an I, which was then an unitialized variable, which then defaulted to 0.
There is actually a python module that does something like that. It goes to the extreme to keep the program running no matter the error you make, arithmetic error are replaced with random results, missing functions skipped, exceptions silently swallowed etc etc. It is obviously a joke but they could benefit greatly from this feature ;)
For those who are interested, I'm pretty sure this is what you're referring to https://github.com/ajalt/fuckitpy. It's worth looking into for the documentation alone.
FuckIt.py uses state-of-the-art technology to make sure your Python
code runs whether it has any right to or not. Some code has an error? Fuck it.
FuckIt.py uses a combination of dynamic compilation, Abstract Syntax Tree
rewriting, live call stack modification, and love to get rid of all those
pesky errors that make programming so hard.
Still getting errors? Chain fuckit calls. This module is like violence:
if it doesn't work, you just need more of it.
Sounds like the Python equivalent of Visual BASIC's "On Error Resume Next" atrocity.
Except you can find "On Error Resume Next" in "production" code. If I ever consider taking contracts doing Visual Basic, the contract will specify that any occurrence of "On Error Resume Next" automatically doubles my daily rate.
You are correct, but please don't refer to the bastardized version of the Jargon file. Wikipedia has a much better and more accurate article, with actual quotes and citations instead of unsourced politically motivated mythology attributed to "some victims":
>Critics of DWIM claimed that it was "tuned to the particular typing mistakes to which Teitelman was prone, and no others" and called it "Do What Teitelman Means" or "Do What Interlisp Means." - Guy L. Steele Jr., Richard P. Gabriel, "The Evolution of Lisp"
The person who bastardized and maintains the Jargon file is a racist, sexist nut job who built his career on attacking the Free Software movement, and who doesn't deserves anyone's respect or attention: http://rationalwiki.org/wiki/Eric_S._Raymond
I hope somebody forks this and creates a version that automatically corrects the method for you at runtime. Why even show an error or throw an exception?
Bonus if the corrections are cached for performance.
As if it wasn't already hard enough to figure out the code path in a ruby application, now we can make it largely indeterminate and dependent on an ever-changing fuzzy algorithm!
Wow. Talk about the wrong approach. When you're having to play trial-and-error to get the right method, you definitely have a problem with your tools - not the language!
I don't know about other editors, but vim has great autocomplete support for ruby built right in. Because of this I don't often even type methods out in full anymore.
Seems like a bandaid approach to fixing a severed artery. The real problem is the lack of desire to read documentation. This also has the problem of sending someone down the wrong path when the wrong "solution" is suggested. Read more documentation and pay attention while you're programming.
I don't think this has to do with a lack of knowledge of documentation, it has to do with simple spelling errors. Quite a number of times I type a method name wrong and upon scanning the code don't see the missing, duplicated, or mistyped letter. This would help a lot with that.
This solution, while creative and laudable, solves a problem that shouldn't exist. It should either be solved by IDE/tooling in a dynamically typed language or by the compiler in a statically typed language. Stop guessing and let your tools do the hard work of remembering method names for you.