6 ms·
Let's Write Some Bad Ruby
- DIVx0 11y agoI have a scratch folder full of stuff like this written in whatever scripting language is closest at hand, ruby, perl, python, etc. I'd wager most people here would have something similar. I wonder if it would be an interesting project to comb though it all and see if any useful tools could be extracted. Probably not, like the code in this blog most of my one-offs are unashamedly terrible.
- n0us 11y agoI didn't really think it was that terrible or hard to understand. I have minimal experience with Ruby and it made sense to me. Doing this sort of thing was why I learned how to program in the first place.
- dopamean 11y agoCouldn't agree more. If you write something for one time use and it works how could it really be bad?
- voltagex_ 11y agoI wholeheartedly recommend anyone to comb through their samples and post them on github - https://github.com/voltagex/junkcode https://github.com/voltagex/junkcode is mine. Occasionally I'll graduate projects to their own repo. This was inspired by http://samba.org/ftp/tridge/talks/junkcode.pdf http://samba.org/ftp/tridge/talks/junkcode.pdf - you may recognise the author!
- chestervonwinch 11y ago> most of my one-offs are unashamedly terrible. I never intended this to see the light of day, but since the topic warrants it, here is a python one-liner I'm using to put the indices of combinations of subsets into one list: combos = map(list,reduce(lambda x,y: x+y,[[c for c in itertools.combinations(range(8),i)] for i in range(1,9)])) yuck. These things usually end up as a result of testing and tweaking in an interactive shell.
- anon4 11y agoI have this dumb C program that scans a folder of .mp3 files and fixes their id3tags from shift-jis encoding to utf-8. Shift-jis isn't officially supported for mp3s, but Japanese Windows uses it as the default encoding for non-UCS2 strings, so when you display a tag that's "latin-1 encoded" on a Japanese locale, it shows up fine, but shows up as gibberish on everything else - https://github.com/moshev/tagfixr https://github.com/moshev/tagfixr
- lighthawk 11y agoThis is the sort of thing a combination of bash/grep/awk/sed is good for also.
- kondro 11y agoTrue, but if you write Ruby all day and are most familiar with it, a script like this takes a matter of minutes to write compared to trawling the man pages of grep/awk/sed to implement the same thing you're only going to throw away after execution anyway.
- sigzero 11y agoSure if you control the environment and can install Ruby. grep/sed/awk are always installed.
- omarqureshi 11y agoPortability becomes a problem though. GNU vs BSD sed/grep :(
- adrusi 11y agoThey do have a shared subset of features defined by POSIX. It's limiting and takes discipline, but it's not really impractical.
- dragonwriter 11y agoPresumably, if you write ruby all day, there is a good chance that the environments you encounter have ruby installed, as well (and they might be even be Windows environments, in which case grep/sed/awk are not "always installed.")
- ricardobeat 11y agoAfter you are familiar with the shell tools, it takes seconds to write something like this, not minutes.
- 11y ago
- tyho 11y agoOr use a language with good tooling: https://godoc.org/golang.org/x/tools/cmd/gorename https://godoc.org/golang.org/x/tools/cmd/gorename
- jgwmaxwell 11y agoWhilst not entirely the point of the article, this could have been accomplished without moving any files by changing the route definition to a scope from a namespace in Rails...
- Breefield 11y agolol I know right, just enough knowledge to be dangerous... that may come off as mean/rude towards the author, but I don't mean it so. I do shit like this all the time because I don't know every little trick with the languages/frameworks I'm using, it's impossible to know it all unfortunately.
- cortesoft 11y agoI think the key point is that it is 'impossible to know it all' I don't think I have ever looked at code I have written more than a few months ago and NOT found a bunch of things I could have done much simpler if I had just known about some feature or trick. I have stopped feeling bad when that happens; now, I figure that the day I stop experiencing that is the day I am no longer getting better as a programmer.
- joshmn 11y agoI had the same thoughts. Why would a company like HashRocket use such an example? Or did they just not know? I don't know.
- stevepike 11y agoAnother awesome tool if you're using emacs is wgrep mode. You get the results of `grep` in a buffer, can edit it like any other text in emacs, and then save writes back to all the original files. Really cool. Emacs macros are wonderful too.
- ricardobeat 11y agoI (frontend/javascript developer by trade) wholeheartedly recommend learning the standard unix tools - bash, sed, grep, awk, xargs - for these tasks. While the syntax is daunting at first, and escaping will be an eternal problem, eventually it starts making sense and you'll be able to do anything in seconds. The work in the post becomes trivial: mv app/views/foo/**/* app/views/ sed -i 's/\([a-z]*\)foo_\([a-z]*\)path/\1\2path/' app/views/**/* or in a more imperative (and probably less efficient) style: for file in app/views/foo/**/*; do sed -i 's/\([a-z]*\)foo_\([a-z]*\)path/\1\2path/' $file new_path=$(sed 's,foo/,,' <<< $file) mkdir -p $(dirname $new_path) mv $file $new_path done
- kr0 11y agoI can't recommend this enough. I was afraid of the shell even having used it quite a lot, preferring to do my changes (like these) with an IDE, and later Perl.
- falsedan 11y agoHow about a nice game of golf? find app/views/foo -depth -type f | while read f; do mkdir -p $(dirname ${f##foo/}); sed <"$f" >"${f##foo/}" -e s'/\([a-z]*\)foo_\([a-z]*\)path/\1\2path/g'; echo rm "$f"; done
- yo-code-sucks 11y agoSexy!
- junke 11y agoI don't do this anymore. I learnt how to use bash, sed, grep, awk, netcat, socat, and as a user, I work in terminals. I accumulated a lot of scripts, to the point where they were the first set of tools I would reach. But it becomes a self-renforcing loop: the more you rely on this toolbox, the more problems you create that are best solved with the same tools and the particular mindset they promote. But for work-related tasks, throwaway code rarely is: your code becomes part of your infrastructure and you have to make it work reliably now and later. After some years, things are not so fun anymore: assembling strings means escaping/quoting characters for different formats and languages. With shell scripts, the path of least resistance is unsafe and introduce many unneeded assumptions. For example, in the above code, globbing in app/views/foo/... in the "for" expression will not work if you have spaces in file names. And if you can get it right, $file is not inside double-quotes; mv will erase any previously existing file. And even though some of the assumptions are valid in context, will they always hold? In order to make them hold, people tend to adapt their problem to fit their tools, not the other way: file names are always in a well-known ascii range, with no space but a specific separator and zero-padding (e.g. myfile_00020, because files are sorted lexicographically). Unless you are willing to use json/xml tools, data is cut into pieces of strings: records are line-separated; each field is colon-separated, each subfield is comma-separated, etc (recursive CSV). And one day, that field which always contain dates in YY/DD/MM format (why not ISO-8601?) starts having a time too, formatted HH:MM. After a painful recovery of trashed data, you add "just one more script" to properly escape colons. Languages are designed with specific goals in mind and writing complex programs is not what scripting languages are optimized for. I now prefer to use language with data-structures, functions, objects, namespaces: less use for strings and regexes. If I try to write onto an existing file, I will be warned (or I can explicitely allow overwriting). Paths are organized as os-independant trees, etc: there are better interfaces to the facility provided by the OS. Coincidently, the need for scripts gradually reduced, at least the one I need to save (I still chain programs on the command-line).
- smithkl42 11y agoI don't know that I could have asked for a better explanation as to why my preferred environment is C#, Visual Studio and Resharper.
- gkya 11y agoIf these lot spend two minutes to understand that code at the end, I'd not depend them for my code. He's just processed some text, that's all, don't bother reading.
- jcummings86 11y agoAs the author I thought I'd comment: I wrote this article, because when I was a very new developer, I was learning a lot more Rails than I was Ruby. It had never occurred to me to use Ruby for scripting until I paired with a well rounded Rubyist. With the influx of people learning Rails, I've talked to many people who know much less about Ruby than I did when I was starting out. This isn't mentioned in the article at all, but it was definitely something I thought about when I decided to write it. Honestly, if this helps push one new dev to go out and decided to actually learn some extra Ruby outside of Rails, I'll be happy. I agree 100% about the shell comments. I know enough shell to do my job, but for me it's quicker to write a Ruby script. Not saying it's the most efficient way, but it is a way, and it's more efficient than doing it by hand. As much as I'd love to be a unix shell wizard, I'd rather be improving my Javascript, or learning more Elixir. As for the namespace vs scope: The example was just a way to end up with a scenario where we needed to change some text. Plus, for clarity, if I don't want my controllers or URL namespaced, my routes and files should reflect that, not work around it with a scope unless necessary for some reason(in my opinion). I actually later thought that I should've used the script on a JS project, just to help highlight the fact that this is totally independent of Rails.
- bad_login 11y agoBefore i thought mastering regexp were a must to have in a day to day programmer job to quickly modify data with different syntax. Now i am still convinced that regexp are still usefull but you will not get it right for the first try due to syntax corner case. The best solution in my opinion is to have easy to use parsers including one for your main programming language. Actually i emacs with its macro feature (not elisp) + racket with regexp (didn't mention earlier but having a strong repl for this kind of incremental script is also a must to have) and sometimes parsers.
- Ch_livecodingtv 11y agoThis probably was the start of writing ruby. I'd recommend you guys watch this video of someone writing bad ruby in contrast. https://www.livecoding.tv/video/rails-refactoring/ https://www.livecoding.tv/video/rails-refactoring/