Support

If you have a problem or need to report a bug please email : support@dsprobotics.com

There are 3 sections to this support area:

DOWNLOADS: access to product manuals, support files and drivers

HELP & INFORMATION: tutorials and example files for learning or finding pre-made modules for your projects

USER FORUMS: meet with other users and exchange ideas, you can also get help and assistance here

NEW REGISTRATIONS - please contact us if you wish to register on the forum

Users are reminded of the forum rules they sign up to which prohibits any activity that violates any laws including posting material covered by copyright

need ruby help

For general discussion related FlowStone

need ruby help

Postby fixstuff555 » Wed Apr 24, 2013 12:23 am

Ok,

I'm having a really hard time with something that should be really easy. I want to create an accumulator in ruby that adds a value present at an input to a running total every time I get a trigger. I can't seem to figure out how to do it with the event method.

I know how I would do this in regular code, but I can't seem to figure out the way to do it in ruby.

I even tried using the example code in the user manual to make a counter and I couldn't get that to work. I have attached what I am attempting to do.

Every time I hit the trigger, I want it to accumulate another 2 for each totalizer.

I'm sure I'm doing a million things wrong. Any advice on how to do this correctly?

The application is for a Gyroscope, where the gyro values at rest are 0, but during movement need to be accumulated at a fixed rate.

I did it without Ruby, but I would like to do it in Ruby - I'm trying to wean myself off simply using FS wire methods...
Attachments
accumulator_nonruby.fsm
(1.91 KiB) Downloaded 967 times
accumulator_fail.fsm
(668 Bytes) Downloaded 933 times
fixstuff555
 
Posts: 151
Joined: Thu Oct 21, 2010 3:24 pm

Re: need ruby help

Postby billv » Wed Apr 24, 2013 7:23 am

fixstuff555 wrote:I'm having a really hard time with something that should be really easy

Yeh, i know......
fixstuff555 wrote:I even tried using the example code in the user manual to make a counter and I couldn't get that to work

Same here, fail fail fail, every attempt at ruby counter.

Nix and I appealed for some help a few weeks back, on how to build ruby counter
viewtopic.php?f=2&t=1342&start=0#p4832
Counter example in Guide seems straightforward, and so do the online ruby counter
tutorials. But every attempt to modify this "User Guide" example, never seems to work.
So obviously were going about it the wrong way.
But Nix and i are both Ruby "noobs", so that might be a answer as to why no-one has "bailed" us out
yet, maybe the "ruby gurus" of the FS community know how easy it is, don't want to leak
to much info, to encourage us to keep trying to get a better understanding of what we are trying to do.
Its very easy to learn nothing when someone else does it for you. And the community is pretty big
on "self-learning".

If this scenario appeals to you, mate, just keep plugging away at it. You'll get it in time.
But if your completly over it/just want to move to next project or whatever....
just say that straight up in your next post, and I'm sure you will get some help.
I suspect they might even "PM" the info to you direct, just to keep Nix and me in the dark,
and make us work harder...... :lol:......who knows.. :?
billv
 
Posts: 1157
Joined: Tue Aug 31, 2010 3:34 pm
Location: Australia

Re: need ruby help

Postby Tronic » Wed Apr 24, 2013 8:57 am

this is an example of how it could be a function of accumulation on condition

Code: Select all
def cond_sum(val,min,max) # conditional sum
   if @prev.nil? then @prev = 0 end
   if (val < min) || (val > max)
   @sum = val + @prev
   @prev = @sum   
   end
   @prev
end

cond_sum(@ins[0],-1,1 )
Tronic
 
Posts: 539
Joined: Wed Dec 21, 2011 12:59 pm

Re: need ruby help

Postby trogluddite » Wed Apr 24, 2013 9:01 am

Only had a very quick glance at the code, but the main problem seems to be with your variables - you're missing a whole load of '@'.

my_variable = a 'local' variable (not remembered between event calls)
@my_variable = an 'instance' variablel (rememebered between event calls)
All schematics/modules I post are free for all to use - but a credit is always polite!
Don't stagnate, mutate to create!
User avatar
trogluddite
 
Posts: 1730
Joined: Fri Oct 22, 2010 12:46 am
Location: Yorkshire, UK

Re: need ruby help

Postby Tronic » Wed Apr 24, 2013 9:25 am

@trog :?:
I did not understand what you mean that is not remembered?
this code only exists in this module then local variables are fine .... no?

EDIT:
I may have figured out, that in this way the function is not unique to multiple calls?
then what's missing?
:? maybe you do not you're referring to my code.
Last edited by Tronic on Wed Apr 24, 2013 2:30 pm, edited 1 time in total.
Tronic
 
Posts: 539
Joined: Wed Dec 21, 2011 12:59 pm

Re: need ruby help

Postby fixstuff555 » Wed Apr 24, 2013 2:21 pm

Yeah, I did a whole lot of @'s too.. It's hard to debug when a message can't be tracked back to the cause, I end missing the tree for the forest.

I had a ton of versions I was hacking away at and finally just decided to post something in the hope I could get advice.

I've had pretty good luck with ruby in regards to formulas and what not, but when I actually start trying to put real code in there it just falls apart. 90% of the time I get hung up on dumb stuff and get frustrated.

The problem for me is this: I can find all sorts of guides and how to's on ruby, but most touch on stuff that is not applicable to ruby as it's implemented in FS. I really need to wrap my brain around how ruby works in Flowstone. The manual is in need of some updating for sure. If all I have is the manual to go by, and I run snippets from it that don't work, I don't have much of anywhere to go, other than looking at high level folks code like yourself Trog.

Granted, your code is wonderfully laid out, and you document it well, but following your code back where it originates (i.e library/module/method) is tough. I would kill for a cross reference tool of some sort to follow code back.

I'm still pounding along though. It's fun when I get something working, but I still have to have that "eureka" moment on the whole object thing. I'm like a big dumb monkey pounding on a keyboard.

EDIT:
Ok. I got the accumulator working. Thanks for the code help Tronic - that was a big help. Only thing I need for it now, is that I would rather use a trigger versus a bool input which is what I have now...
Attachments
counter_test3.fsm
(471 Bytes) Downloaded 922 times
fixstuff555
 
Posts: 151
Joined: Thu Oct 21, 2010 3:24 pm

Re: need ruby help

Postby trogluddite » Wed Apr 24, 2013 10:54 pm

Tronic wrote:I did not understand what you mean that is not remembered?

Well, firstly, I was pointing out that '@variable' is not the same as plain old 'variable' - to Ruby they are two utterly different variables, so the 'mix-n-match' was a big part of the problem.
But it is true, for the way Ruby is used in FS there is a big difference in the way that instance variables and local variables behave.

An instance variable (@) belongs to the whole of the Ruby primitive that it is used inside - doesn't matter if you use it in some plain old code...
Code: Select all
@hi_ruby = "Hello"
output 0, @hi_ruby

...or inside a method like 'event'
Code: Select all
def event
   @hi_ruby = "Hello"
   output 0, @hi_ruby
end


But for a local variable it is very different. A local variable belongs only to the small chunk of code where it gets defined. What do I mean by a "chunk" of code? - Here's a little example - don't worry about what all the method names and commands mean, we all learn those a bit at a time - the lesson is in the #comments....

Code: Select all
def init   # My startup routine
   @my_ruby = "hello"   # this instance variable exists eveywhere in the whole RubyEdit box.
   x = 0  # this local variable 'x' only exists inside the 'init' routine
   output 0, x
end   # 'init' just ended, so local variable 'x' just got killed.

def event
   output 0, @my_ruby   # still the same @my_ruby variable, will still output "hello"
   output 1, x   # error - there is no variable 'x' inside 'event'
   x = 10   # now there is a variable 'x' - a new one that I can only use inside 'event'
   (1...10).each do |y|     #  this makes a loop with 'y' as the counter variable
       output 2, y    # this variable 'y' only exists inside the loop and nowhere else
   end   # end of the loop - 'y' just got killed
   output 1,x  # no error this time because I made an 'event' version of the 'x' variable
   output 2, y  # error, there is no 'y' outside the loop where I used it before
end   #  now that 'event' version of 'x' is dead too!


So the idea is that local variables are VERY local - the general rule is that wherever there is a block of code that ends with 'end', the local variable is only valid inside that block. Sections of code inside curly brackets { } behave the same way.. That's not just method definitions (def....end), but also any kind of loop, and several other more advanced kinds of 'blocks' too.

This also applies to method parameters too...
Code: Select all
def event (i,v,t)
   # i,v and t are only valid inside here
end  # now they are gone


There is one exception to this to watch out for...
In the case of a loop, if there is already a variable in existence just outside the loop, it will get re-used instead of a new one being made....

Code: Select all
def event
  x = 0  #  variable 'x' just for the 'event' method
  (1..10).each do |y|   #  the loop, using 'y' again
      z = y + 1   # 'y' and 'z' are unique to this loop
      x = z + y   # but this is still the 'event' version of 'x'
  end  # kills the 'loop' variables 'y' and  'z'
  output 0,x  #  but 'x' is still here, and had its value changed inside the loop
end


It's a proper mind-bender. The only way I can suggest to really get to grips with it, is just lots of practice - go bonkers making loads of little experimental codes until you get used to it. Once you've nailed it, I promise you will find it very useful - it gives a lot of control over where your variables can and cannot be seen, which saves lots of time trying to dream up new variable names!
All schematics/modules I post are free for all to use - but a credit is always polite!
Don't stagnate, mutate to create!
User avatar
trogluddite
 
Posts: 1730
Joined: Fri Oct 22, 2010 12:46 am
Location: Yorkshire, UK

Re: need ruby help

Postby Tronic » Thu Apr 25, 2013 9:19 am

Thanks for the full explanation,
I think I have understood this well now.

Only dark side is,
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?

perhaps some way that I do not know?
because I would like to follow the rules of the code DRY (Don't Repeat Yourself).

P.S. @trog: thanks always a pleasure to deal with you.
Tronic
 
Posts: 539
Joined: Wed Dec 21, 2011 12:59 pm

Re: need ruby help

Postby trogluddite » Thu Apr 25, 2013 9:06 pm

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'...
Code: Select all
MyModule::say_hello

..but there is also a less cumbersome way - at the start of the code of a Ruby editor put...
Code: Select all
extend MyModule

...and now, the methods works just like a regular one...
Code: Select all
say_hello

'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).
All schematics/modules I post are free for all to use - but a credit is always polite!
Don't stagnate, mutate to create!
User avatar
trogluddite
 
Posts: 1730
Joined: Fri Oct 22, 2010 12:46 am
Location: Yorkshire, UK

Re: need ruby help

Postby Tronic » Thu Apr 25, 2013 11:54 pm

thank you all very clear now.

I take advantage of your willingness to ask you, because you can not do so?
Code: Select all
data = Hash.new
data[:path] =  GraphicsPath.new
data[:pathsize] = [1,1,1,1]
data[:shape] = data[:path].addEllipse data[:pathsize]
data
# => {:path=>#<GraphicsPath:0xc1b3bd4>, :pathsize=>[1, 1, 1, 1], :shape=>nil}

a hash can not contain an instance of an object?
Tronic
 
Posts: 539
Joined: Wed Dec 21, 2011 12:59 pm

Next

Return to General

Who is online

Users browsing this forum: Google [Bot] and 81 guests