Hacker News new | past | comments | ask | show | jobs | submit login

> Method modification is trivially done through "alias" and then just redefining the method in Ruby

I don't know how to convert this into ruby then without needing to manually gensym a bunch of names:

    use Class::Method::Modifiers;
    
    sub foo { 2 }
    
    before foo => sub { warn "before foo 1" };
    
    around foo => sub {
        my ($orig, $self) = (shift, shift);
        warn "around foo";
        (1, $orig->$self(@_), 3);
    };
    
    before foo => sub { warn "before foo 2" };
> As for writing your own constructors, you only need to do so if you actually need to initialize something

Which is required if you're going to use value objects as much as possible rather than spraying mutable state everywhere.




You can do this. I tried to draw up a quick gist, but I am late, and I've been writing too much Rust...

The basic idea is this:

  module Mst
    def self.included(base)
      # define a method on base using define_method named :before, which takes an
      # argument and a block
        # in that method, you grab the method with that name, using .method()
        # you then define a new method, named method, which calls the block and
        # then calls the original method
    end
  end

  class Foo
    include Mst

    def test
      puts "test"
    end

    before :test do
      puts "before"
    end
  end
Module named after you. You can see how the logic only changes a bit for after and around. You could then wrap this up as a library, and all you'd need to do is the include.

http://api.rubyonrails.org/classes/ActiveSupport/Callbacks/F... has an example, I think.


That's really cute.

I hope, however, that you can understand from the POV of somebody who keeps being driven off ruby by ruby being too much work, that "you could make it less work by first porting all the perl5 libraries that make perl5 OO more pleasant" isn't really a convincing solution :)


One of my Twitter followers posted a gist: https://gist.github.com/paulodiniz/39698ac1fe5f62e3180e

Sure, I was just addressing the "I don't know how to do that." Rails offer this for models in certain circumstances, for example.


That's very cute.

Yeah, I was responding to a post that claimed it was trivial; that's cute but not trivial - although it does demonstrate that using 'alias' to rename isn't necessary, which is nice to know.

I can absolutely see how I'd turn this into a full Class::Method::Modifiers re-implementation, so I'll totally stipulate to 'trivial if' :D


I'm not interested in being condescended to, so


Wut? I just complimented the code you posted, and changed my mind from "the unconstructive guy upthread said trivial, which it isn't, but steve's been kind enough to give me enough information to see it's trivial if I write a port of CMM, and said port is basically identical rather than requiring the crappy alias approach".

I've genuinely no idea why you think I was being condescending.


I don't know where steveklabnik hails from, but in the US "cute" is sometimes meant with a condescending overtone. I seem to recall you are from the UK (Scotland?) from the last YAPC I was at, so I suspect this is a dialect difference causing a misunderstanding.


Oooh. Yes. In the above comment, "very cute" should be read as being said genuinely in an approving voice with a big grin, and exactly zero sarcasm.

This may be the first time (yeah, English, but do wear a kilt a fair bit) I've ever run into a problem with an American overdetecting sarcasm.


For what it's worth, I completely agree with the "crappy alias" thing, and wrote a lot about this topic back when I was working on Rails full time (example: http://yehudakatz.com/2009/03/06/alias_method_chain-in-model...).

Ruby eventually added `prepend`, which I demonstrated upthread, and is a genuinely generic, in-language solution to the problem you're talking about.


I dug up my original proposal from 2009, which eventually landed in Ruby 2.0: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/...


Hey! Just woke up to this. Sorry, it seems as someone else mentioned,

  That's cute, but $FOO.
is seen as really condescending here. It's literally diminutive, suggesting that something might be small and pretty, but not worth adult consideration for Real Stuff.

Anyway, if that's not how you meant it, I completely understand. Text is hard. No harm, no foul. Sorry for misunderstanding.


Ok, so, on the one hand, I wasn't trying to be condescending, which is why I didn't say 'but' after 'cute' - the 'cute' was a genuine compliment.

On the other hand, the thread started off with "I've already got stuff in perl that does X and it looks like I'd have to write it myself in ruby", then somebody replied with "this already works in ruby, just use alias" then when I provided an example that wouldn't you showed me how to write a library to support said example in ruby.

So I now know much better 'how to write it myself in ruby', and I am genuinely grateful for that, but it still wasn't an answer to the original question so 'cute' seemed like the appropriate compliment.

The actual answer I was looking for seems to be "people who're bad at ruby will always suggest alias, prepend will handle some cases, and then you can write not that much code if you want the other cases, but there's no perl5+Moo quality experience to be had without implementing at least part of it yourself".

Which is totally fine by me, I just need to talk somebody better than me at ruby into implementing it and then try and convince everybody to upgrade :D

(also, if you have a suggestion for a word other than cute that would express "really pretty even though it doesn't answer the question" while seeming positive rather than negative about this fact I'm all ears)


:)

I sat on it for another evening, but I'm not sure of the best word for you, to be honest.


"Neat"?


mst might speak for himself at another time, but i have a personal reason to post, so i will say this:

Please do not take this conversation as an affront and throw away what has so far come of it. It has shown you, and Ruby at large, an API that has been proven to be good and useful, and the Ruby community has come up with a way to implement it in a generalized way. I hope to someday be able to learn Ruby and use its OO with similar ease and pleasure as i can use the OO system in Perl 5. So please, do not throw this away. It is a valuable chance to do the same thing Perl has done so many times: Recognize something useful and make it your own.


Steve and I had a previous similar conversation; this one got further subject wise, but the original was also a fair few posts deep and we didn't accidentally piss each other off that time.

Pretty sure we'll manage to resolve the confusion shortly.


For what it's worth, the `prepend` API in Ruby, which I advocated for back when I was working on Rails, works pretty nicely:

https://gist.github.com/wycats/0a354a96d00d47fa4e04


Oh, that's even better. Is there an around/after equivalent or are those still best implemented with Steve's thing?


"before", "after", and "around" method modifiers are pretty common in Ruby Aspect-Oriented Programming libraries (AOP has pretty much fallen out of favor for Ruby, but I'm pretty sure at least some of these are still maintained.)


> I don't know how to convert this into ruby then without needing to manually gensym a bunch of names

Sounds like you want something like: https://github.com/nicknovitski/modifiers

> Which is required if you're going to use value objects as much as possible rather than spraying mutable state everywhere.

Using Ruby's Struct class for this often avoids needing explicit constructors.


Except that package doesn't provide before/after/around.

What I really want is CLOS. But the closest in perl/python/ruby/javascript is Moose/Moo.

There's also, btw, a moosex gem where some rubyists are trying to port the perl stuff - but Moose/Moo are pervasive in modern OO perl whereas most existing ruby code is done the ugly, boilerplate-y way.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: