Hi there,
Nice to see my shiny red boxes getting some use - and thanks for the credit.
Sadly, I have some bad news for you - your class does not work; at least not the way intended. Attempting to scale '@a' just results in a "No Method" error.
It's a great idea though; converting one number range to another is such a common thing to need - and no problem with your maths.
It's cool to see someone else having a go at extending Ruby, and you're thinking along the right lines - so I'll go into a bit of detail about why it doesn't work
When you create a class you are defining a whole new type of object. The methods inside the class decide what you can (and cannot) do with one of those objects. So a "Door" class object might have "open" and "close" methods, but probably not "eat" and "drink". But defining "Door" as a class doesn't create a 'Door', it just tells Ruby how to make one. To actually get hold of one in the program code, you need to make a new one using "new".
- Code: Select all
myFrontDoor = Door.new
The methods inside a class can only be used by an object of that class - so in your case a "Scale" object could use the method "convert between", but other types of object can't - which is why feeding in '@a' gives a "No Method" error - because it is 'Float' class object not a 'Scale' one.
So we could try making a new 'Scale' class object.
- Code: Select all
@myScale = Scale.new
@myScale.scale_between(0,1,50,100)
But that doesn't help either - "Undefined method '-'". Because '@myScale' is a 'Scale' object, it has no maths methods, 'scale_between' is the only one defined for it, along with a few standard ones that every object gets. And if you look at the code - there's nowhere for the input number to be put in any more.
OK - if it is float numbers that we want to scale, how about defining '.scale_between' as a method of the 'Float' class; then it would be working with the right kind of objects. You can add new methods or modify old ones for a class any time you like by just putting a new "class XXX ... end" section in the code with the same name.
NEVER DO THIS!!
It is so very, very tempting to modify the built in classes, but they are shared everywhere in Ruby - including across multiple VST plugin exports. If you ever use modules shared around the forum, you just never know how your modifications might affect everyone else's programming, or whether their Kernel class mod's will affect yours. It's just a very bad habit to get into and is best avoided.
Really a class isn't what's needed. Rather than being a type of object, scaling is something we want to do TO objects - we want the 'scale_between' method to be something we can do to any number object that we choose.
And you can do that by changing only one word of code...
Rather than a class, you want a module. A module never makes new objects of its own, it is just a container for keeping definitions inside so that you can re-use them easily.
First, change "class Scale" to "module Scale"
This will throw an error - Ruby is just confused because it remembers old class definitions, and won't let you re-use the same name for a module. No problem - save file, close, and re-open FS to clear the memory.
Better still use "module Urn_Scale'The same clashing of names between modules and classes can happen no matter where in a schematic you make them, and even between different schematics. 'Scale' is a common word and concept that other people might use in their own modules - so making the name unique by adding a personal tag will make clashes much less likely.
I've just recently modified all of my classes with the prefix "Trog::" for exactly this reason.
To use your new 'Scale' module, there are a couple of ways....
Attach the new method to each object when you need to.You can add the 'scale_between' feature to any object you like by using the '.extend' method.
- Code: Select all
@x = 10
@x.extend(Scale)
@a.scale_between(0,,200,500)
The 'Scale' module could have hundreds of methods, but you could add them all at once to any object this way. you just have to be careful that the type of object is appropriate for the methods. 'scale_between' won't work on strings, because the maths won't work on them, for example..
Use 'scale_between' as if it was just a normal method.If you add an extra argument 'input_value', and then use 'input_value' instead of 'self' inside the method definition, then you get something like a normal FS method - there's no self, you just put all the values in as arguments.
And if you write the method to look like a regular FS one, then you can add it easily to any Ruby module that you choose.
You just use 'extend' again - but with no object this time, so that it is the Ruby primitive itself that gets extended.
- Code: Select all
extend (Scale)
This is just the same as if you had written out the method in a normal run of code - but it saves you from having to type it over and over again when you want to use it in load of places. And you would use the method in just the same way as a 'bare' method, without any 'self'...
- Code: Select all
scale_between(@a,0,1,100,250)