Having read a couple weeks ago that autoload is officially deprecated, Matz discourages use of it. What is to replace it? What should developers do instead? I used it in some command-line gems to save unnecessary loading of libs that may never be used, as well as in JRuby to prevent the same for .jar files.
I've seen people use the EasyLoad gem, it claims to be a autoload alternative. It loads based on directory module naming convention.
Related
I have a gem I want to add types to (either by submitting a PR or by forking to use just in my project), but the documentation does not give any more guidance other than to create an /rbi folder.
Thinking out loud, should it mirror the files in lib/ with added type signatures, or should it be one large file (per version?) like the signatures in sorbet-typed?
I don't know of any gems doing this yet, and the documentation doesn't mention it either.
I recently went through this process for one of my gems - pdf-reader. It was my first experience with sorbet (so I'm no expert), and I also noticed the lack of documentation for the specific use case of adding types to a gem.
I ended up generating the initial rbi file using parlour, which put them all into a single file: https://github.com/yob/pdf-reader/blob/480aa240a531cd6f97a46a29279f19025821e886/rbi/pdf-reader.rbi
Sorbet seems happy with that, so I haven't changed it.
I have a project with many Ruby files, loaded by external program with embedded Ruby interpreter (and some other libraries). I'm trying to use RubyMine and Rubocop to help with development, but the problem is that the said embedded interpreter is of version 1.9.2 and can't be upgraded in any way. Is it possible to still use the Rubocop or other linter inside RubyMine and at the same time to make sure the code is compatible with old interpreter?
Yes you can, Check this out and then let RuboCop know the oldest version of Ruby which your project supports with updating .rubocop.yml file:
AllCops:
TargetRubyVersion: 1.9
The short answer is that yes, it is possible to change the linter used in RubyMine, there are complete walk-throughs on JetBrains site explaining how. I don't know off the top of my head any linters that specifically work for pre-2.0 versions of Ruby, not to say they don't exist.
The longer answer is that it really won't make much difference if the interpreter is running through another program, and not using a real Ruby installation, and any linter is not going to reliably work for you. There will be plenty of code that a linter will still think is perfectly acceptable, but fail when running in an embedded VM.
# Linter thinks this perfectly fine, part of 1.9.2 standard library
require 'base64'
# Still thinks this perfectly fine. This all fails miserably though
Base64.encode64('My string')
The most obvious examples would be the entire standard library, gems, rake, and anything that is not part of the "core" library. Basic rule of thumb, if you have to require a script (excluding your project's local scripts), it is not going to work.
Another reason it could never be reliable is that you do not know if the embedded Ruby interpreter has been altered, or removed features from Ruby for their purposes, and a linter would have even less way of knowing that. Years ago I dabbled with the RPG Maker series, and discovered the hard way that their were certain built in features of Ruby that were removed (or at least hidden) from their custom build.
If you are familiar with Ruby, then you can obviously steer clear of the major and most common 2.0+ changes that Ruby implemented to the core library, but the only reliable way to know (even with a linter), is testing, which you will need to do anyway ( or at least you should). RubyMine has good support for automating this with Minitest and RSpec.
I have some perl applications & modules that I use for a number of tasks.
I would like to bundle these up and place a Coca wrapper around them, so I can distribute them to other people.
Assuming I can force use of the bundled OSX perl and include the modules I need inside my application, is there any real problems with doing this? I really do not want to re-implement everything I have already done.
There is nothing wrong with using the system-provided tools, include Perl. Things to consider:
The version of Perl changes from release to release. So if you need to support 10.4-10.7, you wind up with very diverse versions of Perl to support.
It can be tricky to include your own versions of modules, particularly if those modules rely on other modules, and most especially if those modules include compiled code.
Occasionally users mess with their system Perl more than you would like. In particular, they might install new modules or upgrade existing modules. Ideally you can say "don't do that," but it can create problems.
My team has had nightmares dealing with Net::SSL on different versions of OS X. We finally have removed Perl entirely from our code base due to the headaches of managing all the different versions of Perl and of Perl modules that might be in the system libraries.
But if you keep your dependencies simple, then there's no problem using the system Perl.
As long as you employ good coding practices, it should be fine. I've never use Perl in a Cocoa application myself. You might want to check out Camel Bones: http://sourceforge.net/projects/camelbones/
Its a Perl/Cocoa bridge. Never used it myself, but it may help.
With my code I'm using autoload for lazy evaluation so I can load the program faster and load the files when needed, I'm not seeing so many people using it, but with Thin project I noticed autoload has been used widely, anyways just wanna know if there is any risk to use it .
autoload is not threadsafe and will be deprecated in the future versions of Ruby. Here is the proof by Matz (creator of ruby).
I just started learning Ruby coming from Java. In Java you would use packages for a bigger projects. Is there anything equivalent to that in Ruby? Or what is the best way to achieve a package like setting?
The way I'm doing it right now is 'load'ing all the needed class into my new Ruby file. Isn't there a way to tell my current Ruby class to use all other Ruby classes in the same folder?
Cheers,
Mike
There's three kinds of package loading in Ruby:
Explicitly loading a library with require
Implicitly loading a library using autoload
Importing a library with gem
The require method is the most direct and has the effect of loading in and executing that particular file. Since that file may go on to require others, as a matter of convenience, you may end up loading in quite a lot at once.
The autoload method declares a module that will be loaded if you reference a given symbol. This is a common method to avoid loading things that you don't need, but making them automatically available if you do. Most large libraries use this method of loading to avoid dumping every single class into memory at once.
The gem approach is a more formalized way of packaging up a library. Although it is uncommon for applications to be split up into one or more gems, it is possible and provides some advantages. There's no obligation to publish a gem as open-source, you can keep it private and distribute it through your own channels, either a private web site or git repository, for instance, or simply copy and install the .gem file as required.
That being said, if you want to make a library that automatically loads a bunch of things, you might take this approach:
# lib/example.rb
Dir.glob(File.expand_path('example/**/*.rb', File.dirname(__FILE__))).each do |file|
require file
end
This would load all the .rb files in lib/example when you call require 'example'.
You probably want to use require rather than load, since it should take care of circular references.
If you want to grab all the files in a given folder, that's easy enough:
Dir.foreach("lib"){|x| require x}
Your other option is to have a file that manually requires everything, and have your other files require that.
You should also look at wrapping the code in your libraries with a module block, to give them their own namespaces.
That said: rightly or wrongly, I tend to feel that this is the one area -- perhaps the only one -- where Ruby is less powerful than Python, say, or Java.
I understand your feeling. It's an ordinary problem you have to face when coming from another language like Java. I'd say try to study Ruby modules but you deserve a longer reply. So my advice is reading a good Ruby book like Eloquent Ruby.