Tronic wrote:P.S. @trog: thanks always a pleasure to deal with you.
No problem - FS and Ruby will thrive the more we share our discoveries with each other - everyone's a winner.
Tronic wrote:how you can make a reusable method, only in the module in question, without creating a class?
Possible? I think it's impossible, if understood well,
there is no system to create a new instance of the method without surrounding it in a class, right?
Yes, that's pretty much right - RubyEdit boxes are strange creatures, even compared to normal Ruby coding - they act as containers from which methods and variables cannot leak out (they are Ruby objects with singleton methods, in Ruby speak)
This is vital - because we need to be able to drag multiple knobs etc. from the toolbox without them interfering with each other by sharing variables that have the same name - so it is quite a clever solution really, but does lead us to use Ruby in a different way than the standard textbooks etc.
If you want to share only some method definitions, but without creating a whole new class of obects, there is a way using modules...
Code: Select all
module MyModule
def say_hello
output 0, "Hello"
end
end
So we now have a 'say_hello' method defined, but at the moment we can't actually use it - the module "wrapper" hides it away, and it doesn't belong to any particular object or RubyEdit box. However, the module 'wrapper' is global and can be seen anywhere that you are using Ruby.
If we now go to another RubyEdit box, we can get access to the new method by using it's full name 'path'...
..but there is also a less cumbersome way - at the start of the code of a Ruby editor put...
...and now, the methods works just like a regular one...
'extend' does pretty much what is says - it takes all of the code inside the module, and adds all the module's methods to the new RubyEdit instance. It's just as if you had cut and pasted the 'say_hello' code into the Ruby box - and the module can contain as many method definitions as you like.
The great thing about this technique is that the module methods will only appear inside Ruby edit boxes where you use the 'extend' command - so you could even use it for common things like 'event' methods, and it won't clash with other Ruby boxes that want to use their own 'custom' versions.
The downside is that the methods inside the module must only use local variables, and not any @instance variables - because any @instance variables would belong to the
module's RubyEdit box, and not the one that's using 'extend'. For example, if you were sharing an 'event' method, you could get at the input values using the 'v' variable (from 'def event i,
v, t ), but not by using @in or the '@input_label' variables.
But that's not too big of a limitation - it's probably a technique best used for things like big chunks of number crunching maths etc. anyway.
As you say, it's a good way to put DRY into practice, and can save a whole load of cutting and pasting, or using sync'ed modules. Ruby is well set up for this sort of thing - they call it "Mixins" in Ruby speak.
In fact there are some modules designed to be used like this in the standard Ruby language - such as 'Math; which adds trig functions etc. - you can always get at the adavnced maths functions by typing something like...
Code: Select all
x = Math::sin(angle)
y = Math::cos(angle)
...but if you get bored of typing 'Math::' before every cos/sin function, you can just do...
Code: Select all
extend Math
x = sin(angle)
y = cos(angle)
As with classes, you do need to use a little care if making your own modules...
1) Other Ruby boxes might make a module with the same name.
2) The 'extend'ed module might be initialised before the one with the module inside it, and so will give a "Not found" error.
i see you've spotted my
other thread about those, so I won't dwell on them here (DRY, he he!)
There's also one other thing to watch out for...
If you edit your module code, other Ruby boxes won't see the edits unless they run the 'extend' command again; otherwise they'll just carry on using the old version. This is a little tricky to deal with, because ideally you only want to use extend once, when the schematic is loaded. Once your new module is finished and being used in other schematics, that's fine; but it's usually simplest to do the module writing and testing in a small schematic all to itself until you know it's ready to 'deploy'.
It's also possible to put modules and classes into separate files on disk, and load them using the 'load' or 'include' methods. Something to experiment with maybe, but personally, I'm not sure it suits plugins very well - it means that you have to distribute a load of extra files with your VST .dlls and exe's, which the user has to be sure and put in the right place. So I just put them inside an FS module (very appropriate!), and stick them in my toolbox, ready for dragging out whenever I need them (and easy to share on the forum too).