I am testing a piece of Rails code that reads:
sleep(10.0)
In my RSpec tests, calling:
Kernel.should_receive(:sleep).exactly(1).time
failed and the test slept for ten seconds. This led me to conclude that sleep() in a Rails program isn't calling Kernel.sleep(). I verified this by changing my Rails code to:
Kernel.sleep(10.0)
... after which my RSpec tests passed (and the test didn't sleep).
This leads to a specific and a general question:
What implementation of sleep() does Rails use (I'm running Ruby 1.9.3 / Rails 3.2.1)?
From the interpreter, what's the easiest way to find the source code for any function?
The implicit receiver, when you don't specify an explicit one, is self, not Kernel. (Why would you think that?)
So,
sleep(10.0)
is roughly the same as
self.sleep(10.0)
and not at all the same as
Kernel.sleep(10.0)
So, it is calling Kernel#sleep on self and not on Kernel. Which means you need to set an expectation on whatever object self is in that particular method.
Related
I am submitting solutions to Ruby puzzles on codewars.com and experimenting with how locked into the testing enviroment I am for one of the challenges.
I can redefine the classes used to test my solution but they are defined by the system after I submit my code. If I freeze these objects, the system cannot write over them but a RunTime error is raised when it tries to.
I'm fairly new to Ruby, so I'm not sure which parts (other than falsiness and truthiness) are impossible to override. Can I use Ruby code to force modification of frozen objects to silently fail instead of terminate the program or is that bound up in untouchable things like the assignment operator or similar?
The real answer here is that if you might want to modify an object later, you shouldn't freeze it. That's inherent in the whole concept of "freezing" an object. But since you asked, note that you can test whether an object is frozen with:
obj.frozen?
So if those pesky RuntimeErrors are getting you down, one solution is to use a guard clause like:
obj.do_something! if !obj.frozen?
If you want to make the guard clauses implicit, you can redefine the "problem" methods using a monkey patch:
class Array
# there are a couple other ways to do this
# read up on Ruby metaprogramming if you want to know
alias :__pop__ :pop
def pop
frozen? ? nil : __pop__
end
end
If you want your code to work seamlessly with any and all Ruby libraries/gems, adding behavior to built-in methods like this is probably a bad idea. In this case, I doubt it will cause any problems, but whenever you choose to start hacking on Ruby's core classes, you have to be ready for the possible consequences.
I just discovered Ruby's metaprogramming (after 7 years of using Ruby, it was about time!) and I have this question:
Assuming I run a program that uses class_eval and other metaporgramming functions to add methods to a class, is there an easy way, when re-running the same program, to have these new methods already defined, or do I have to program my own system which, every time class_eval is used, also save the generated code in a file in order to re-evaluate it the next time I run the program?
Thanks
This is not how it's done. A proper way is, when you run the program next time, to run all those calls to define_method, class_eval (and whatnot) again and define methods in run-time.
Imagine what would happen if generated methods persisted in your source code? Would you like your attr_accessor to replace itself with two new methods?
What if you're writing such a meta-method yourself and you change it. How do you think all those saved generated methods will be updated?
I don't know where you read about metaprogramming, but I strongly recommend this book: Metaprogramming Ruby. It should clear your head. :)
You can not (with eval, and self-assembled strings you could, but that is not metaprogramming anymore) and should not do that, even ruby's standard library is re-evaluated on program launch.
Another possibility would be forking, unicorn is a good example for that. Evaluate all your method definitions, and then start spawning child processes, which are copies of the "master" process. This saves you the time of re-evaluating all your code, as forks are pretty fast compared to that.
Similar to __callee__, is there something which returns the calling method? I realize there is the caller which I amble to strip the name of the caller method from but I am curious is there is a standard method for returning the name of the calling method without any other information along with it.
There is no such feature in MRI. But there are some alternatives.
In case you happen to use Rubinius, you can do this instead of parsing caller:
Rubinius::VM.backtrace(1, false).first.name
#=> :calling_method_name
You can also use a gem to parse the result of caller for you. It should work for any Ruby > 1.9.
The answer to this SO question describes how you can do some simple parsing yourself.
And finally, there appears to be work in progress on getting a feature like this into Ruby 2.0, although the relevant ticket has not been updated for a while.
So, here's the deal. I'm currently working in a Ruby on Rails environment and have been for ~1 year now. Before that I was in C++/Java land for almost a decade. I'm (still) trying to figure out what the Ruby way is when it comes to asserts.
I'm not worried about the technical detail. I know TestUnit has asserts which can be used in the testing environment and I know I can add my own assert methods to my Ruby project and use them in production Rails to lock down known conditions. The question is: What is the Ruby way for ensuring something in code that I know should/not happen?
For the record, I've been asserting in tests and raising in production. I still can't help but miss my production asserts...
Asserts really shouldn't be used in production code for two reasons.
assert x is very functional, and as such hard to read. Using a raise/if combo adds readability.
assert doesn't make it clear what error will be raised if the condition fails. While,
raise ObscureButInformitiveError if condition
lets the application layers further up do something relveant. Such as emailing an admin, or writing to a perticular log.
Let the error happen, then check the logs for what went wrong, then fix it.
Rails catches all uncaught exceptions automatically, it will only mess up the single request the error happened in.
There's no official non-test assertions in Ruby, but there are gems.
For instance Jim Weirich's Given looks promising. Although its main focus is testing environments (rspec / minitest), but it also:
... provides three assertions meant to be used in
non-test/non-spec code. For example, here is a square root function
decked out with pre and post-condition assertions.
require 'given/assertions'
require 'given/fuzzy_number'
include Given::Assertions
include Given::Fuzzy
def sqrt(n)
Precondition { n >= 0 }
result = Math.sqrt(n)
Postcondition { result ** 2 == about(n) }
result
end
To use the
non-testing assertions, you need to require the 'given/assertions'
file and then include the Given::Assertions module into what ever
class is using the Precondition / Postcondition / Assert methods. The code
block for these assertions should always be a regular Ruby true/false
value (the should and expect methods from RSpec are not available).
Note that this example also uses the fuzzy number matching, but that
is not required for the assertions themselves.
Most of the code I write is in Ruby, and every once in a while, I make some typo which only gets caught after a while. This is irritating when I have my scripts running long tasks, and return to find I had a typo.
Is there an actively developed lint tool for Ruby that could help me overcome this? Would it be possible to use it across a system that works with a lot of source files, some of them loaded dynamically?
Take this snippet as an example:
a = 20
b = 30
puts c
To win bounty, show me a tool that will detect the c variable as not created/undefined.
ruby -c myfile.rb will check for correct Ruby syntax.
Reek checks Ruby code for common code smells.
Roodi checks Ruby code for common object-oriented design issues.
Flog can warn you about unusually complex code.
[Plug] If your project is in a public Github repository, Caliper can run the latter three tools and others on your code every time you commit. (Disclaimer: I work on Caliper)
You could give Diamondback Ruby a try. It does a static typecheck of Ruby code, and will thus blame you for using an undefined variable.
While DRuby is an ongoing research project, it already works quite well for small, self-contained Ruby scripts. Currently, it is unable to analyze much of the Ruby standard library “out-of-the-box”. Currently they are working toward typing Ruby on Rails (see their most recent papers).
RubyMine (http://www.jetbrains.com/ruby) does the trick:
alt text http://img707.imageshack.us/img707/5688/31911448.png
None of the below will do all the analysis that RubyMine does.
NetBeans Ruby pack
Aptana RadRails
gVIM (with syntastic plugin by scrooloose)
Each of these has the capacity to identify syntax errors such as wrong number of parentheses, too many defs, ends, braces, etc. But none will identify invalid method calls the way RubyMine does.
Here's why: it's difficult.
Since Ruby is extremely dynamic (and methods like 'c' could easily be generated on the fly), any editor that tries to identify non-existent variables/methods would need to have a large part of the entire evironment loaded and multiple program flow paths constantly tested in order to get accurate 'validity' results. This is much more difficult than in Java where almost all programming is static (at least it was when I dropped that hat).
This ability to easily generate methods on the fly is one of the reasons the community holds testing to such high esteem. I really do reccomend you try testing as well.
Have a look at RuboCop. It is a Ruby code style checker based on the Ruby Style Guide. It's maintained pretty actively and supports all major Ruby implementations. It works well with Ruby 1.9 and 2.0 and has great Emacs integration.
Yes. Test::Unit
Ok, I know you already know this and that in some sense this is a non-helpful answer, but you do bring up the negative consequence of duck typing, that there kind of is (at this time) no way around just writing more tests than something like Java might need.
So, for the record, see Test::Unit in the Ruby Standard Library or one of the other test frameworks.
Having unit tests that you can run and rerun is the best way to catch errors, and you do need more of them (tests, not errors :-) in dynamic languages like Ruby...
nitpick might be what you're lookng for.
With this code:
class MyString < String
def awesome
self.gsub("e", "3").gsub("l", "1").uppercase
end
end
puts MyString.new("leet").awesome
... it outputs:
$ nitpick misspelling.rb
*** Nitpick had trouble loading "misspelling.rb":
NoMethodError undefined method `uppercase' for "133t":MyString
Nothing to report boss! He's clean!
Have not used it yet, but sounds promising (will update when I've tested this).
https://github.com/michaeledgar/laser
Static analysis and style linter for Ruby code.
Pelusa is nice, but is working in rubinius only. This shouln't be a proplem for people familar with RVM though.
avdi#lazarus:~$ irb
>> a = 20
=> 20
>> b = 30
=> 30
>> puts c
NameError: undefined local variable or method `c' for main:Object
from (irb):3
>>
There ya go, the tool is called "IRB". Do I get the bounty?
I'm only half joking. I wrote this second answer to hopefully drive home the point that in Ruby, if you want to know that something is defined or not, you have to run the code.