Page 1 of 2

Not Flowstone related - Ruby code question

Posted: Mon Apr 20, 2020 9:53 pm
by tulamide
Maybe trog or TheOm can answer my question, that simply is "what the eff is going on here?"

I was looking for hardware accelerated graphics libraries with possible usage in Flowstone. One of them was Cairo, which comes with Ruby bindings. Of course they are in a gem, and I was looking for a way to implement it somehow in Flowstone. But the very first code I saw already discouraged me. But I'm also curious. I've taken out the rest of the module definitions, because I don't understand this class definition. A class, defined within a module with self as parent? And then the argument setter method definition! Can somebody explain to me, what this code actually does? (The lines are 100% original, didn't touch them at all, although it is a strange distribution of instructions)

Code: Select all

module Cairo
  class << self
    def __add_one_arg_setter(klass)
      names = klass.instance_methods(false)
      names.each do |name|
        if /^set_(.*)/ =~ name and
            not names.include? "#{$1}=" and
            klass.instance_method(name).arity == 1
          klass.module_eval("def #{$1}=(val); set_#{$1}(val); val; end")
        end
      end
    end
  end
...

Re: Not Flowstone related - Ruby code question

Posted: Tue Apr 21, 2020 9:44 am
by TheOm
Essentially this adds a Module method (same as a class method aka a "static" method) called __add_one_arg_setter to the module.
For a real explanation of the class << self thing look at this old stackoverflow question:
https://stackoverflow.com/questions/250 ... om-in-ruby

The method does some metaprogramming. It takes a class and for every instance method that starts with set_ it adds a ruby-style setter that just delegates to that method. (For example if a method set_x(val) exists it adds the method x=(val) ).
I haven't found any actual use of __add_one_arg_setter in the code though, just an undef, so not sure why they need it.

Re: Not Flowstone related - Ruby code question

Posted: Tue Apr 21, 2020 6:55 pm
by CoreStylerz
Not so familiar with Ruby but looks like it read all class public methods in the variable "klass" through reflection.
if method is a setter (using regex to the method name) and there's a condition not clear to me:
not names.include? "#{$1}=" and
klass.instance_method(name).arity == 1

Than eval the method and create a variable in the script scope to be passed in

Re: Not Flowstone related - Ruby code question

Posted: Tue Apr 21, 2020 11:42 pm
by tulamide
OH!
I am so used to 'def self.something' that I didn't get it! Regarding the setter meta, I don't really see the advantage of doing that? Seems more like a quick hack of somebody who was too lazy to define attr_writer (or _accessor) where needed?

::arity was new to me as well, but I read about it and it is actually quite useful in such cases. It returns the number of arguments, a method expects (or -1 when the splat operator is used). It gets more complicated if the arguments are a mix, though. https://ruby-doc.org/core-2.5.1/Method.html#method-i-arity

$1, $2 etc. are basically globals, but with the special task of storing the return value(s) of a regular expression (as was used here). #{} is placing an object in a string. I just can't read the regex itself. I guess that would reveal a rather simple thing like 'may not include mymethod=' or something similar?

However, that has helped me. Thank you both very much!

p.s. TheOm, I hope you will soon come up with some fine Ruby based module? It was such a long posting break!

Re: Not Flowstone related - Ruby code question

Posted: Wed Apr 22, 2020 12:03 am
by CoreStylerz
tulamide wrote: I just can't read the regex itself. I guess that would reveal a rather simple thing like 'may not include mymethod=' or something similar?


Is more or like:
^set_ = begin with
(.*) = capture anything "." for unlimited repetitions "*" in a group ()

Re: Not Flowstone related - Ruby code question

Posted: Wed Apr 22, 2020 3:08 pm
by trogluddite
TheOm wrote:I haven't found any actual use of __add_one_arg_setter in the code though, just an undef, so not sure why they need it.

The method is used within the C-extension which wraps the Cairo library (required as "cairo.so" in the Ruby code, and defined in the "ext/cairo" sub-folder of the Git repo). Since C++ code can't use "=" in member-function names, the "set_..." naming convention is used internally, and then the method in question is called to convert these into Ruby attr_writers when the extension is 'required'. Once the extension is loaded, the conversion method isn't needed any more and is undefined.

So the method does serve a useful purpose; though I agree with tulamide that it's coded in a pretty clumsy way - and there's even part of it that does nothing useful at all (presumably a silly oversight)...

Code: Select all

include? "#{$1}="

This will always be false, as the Array of method names will contain Symbols, not Strings!

PS) The use of the C-extension implies that some Visual Studio C++ compilation would be required to get the library working in FlowStone.

Re: Not Flowstone related - Ruby code question

Posted: Wed Apr 22, 2020 5:45 pm
by RJHollins
i didn't understand most of these last few post ... however ...

I still found it interesting ! Have I been in 'isolation' too long :shock:

Re: Not Flowstone related - Ruby code question

Posted: Wed Apr 22, 2020 9:44 pm
by trogluddite
RJHollins wrote:i didn't understand most of these last few post ... however ...

I still found it interesting ! Have I been in 'isolation' too long :shock:

You expect to "understand" my rantings? Oh dear, yes, I think you really are starting to crack under the strain! :?

Actually, I shouldn't really admit this, but I have a special tool that I use for writing my "incomprehensible but interesting" Ruby posts...
ruby_oracle.fsm
(12.9 KiB) Downloaded 933 times
;)

Re: Not Flowstone related - Ruby code question

Posted: Wed Apr 22, 2020 11:49 pm
by deraudrl
trogluddite wrote:Actually, I shouldn't really admit this, but I have a special tool that I use for writing my "incomprehensible but interesting" Ruby posts...
ruby_oracle.fsm
;)
Oddly enough, it works exactly as well in the alpha as it does in 3.0.6. 8-)

Re: Not Flowstone related - Ruby code question

Posted: Thu Apr 23, 2020 3:13 am
by RJHollins
trogluddite wrote:
RJHollins wrote:i didn't understand most of these last few post ... however ...

I still found it interesting ! Have I been in 'isolation' too long :shock:

You expect to "understand" my rantings? Oh dear, yes, I think you really are starting to crack under the strain! :?

Actually, I shouldn't really admit this, but I have a special tool that I use for writing my "incomprehensible but interesting" Ruby posts...
ruby_oracle.fsm
;)

:lol:

thanks .... I needed that.

mmm ... I was actually following along with the Sir Random text :shock:

Then again ... I prefer the Live versions of your Rants :D

side note: a 'baby's behind' has NOTHING over my hands. After all the wash and sanitizing. There could be a lot of blood and blisters the next time I get to play :roll: