Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re^7: RFC: Simulating Ruby's "yield" and "blocks" in Perl (Python)

by MonkOfAnotherSect (Sexton)
on Apr 26, 2013 at 15:13 UTC ( [id://1030852]=note: print w/replies, xml ) Need Help??


in reply to Re^6: RFC: Simulating Ruby's "yield" and "blocks" in Perl (Python)
in thread RFC: Simulating Ruby's "yield" and "blocks" in Perl

(I've just trimmed the code back in http://perlmonks.com/?node_id=1030806 to use a closure rather than a class -- needed a class back when it was a coroutine... not so much anymore)

Here be Python...

A decorator in python is just syntactic sugar, remembering that Python has first class functions and classes:
def deco(callable): # Do something with callable retval = callable return retval @ deco def example1(): pass #...is identical to def example1(): pass example1 = deco(example1)
A decorator doesn't have to return a callable -- eg you could decorate class SomeClass with @id, and get a fairly useless number bound to the name SomeClass. And in theory you could fiddle with the code in the callable that's passed, and return the identical object but you wouldn't.

One cannot @decorate a lambda, and "_" as a name is just convention.

  • Comment on Re^7: RFC: Simulating Ruby's "yield" and "blocks" in Perl (Python)
  • Download Code

Replies are listed 'Best First'.
Re^8: RFC: Simulating Ruby's "yield" and "blocks" in Perl (Python)
by LanX (Saint) on Apr 26, 2013 at 17:54 UTC
    Thanx, it's clear now.

    I was just surprised that you need two decorators!

    I thought you could simply do something like

     test(def _(x): print("You are in block %s" % x))

    (like  test sub { print("You are in block $_[0]") } in Perl)

    Just to get closer to the Ruby feeling and to achieve this

    >>> def _(x): ... print("You are in block %s" % x) ... >>> test(_) In test You are in block 1 back in test You are in block 2 test lambda a: print("You are in block %s" % a)

    But one needs decorators to manipulate a literal function.

    Obviously, there is only this way to do it.

    FWIW Python decorators could quite easily be simulated in Perl with attributes.

    I will post this soon (if I can't find it already on CPAN) =)

    Cheers Rolf

    ( addicted to the Perl Programming Language)

      If you used a non-keyword such as "send" instead of "yield" you could do Evil and avoid the first decorator. This is left as an exercise. As for the second decorator, sure 'test(lambda a: print("You are in block %s" % a))' will work, but when you require more than one line you're back to using a decorator unless you want to do something truly horrible.

      Don't want to do something truly horrible.

      -T. "A gentleman is someone who knows how to play the bagpipes but doesn't."

        > As for the second decorator, sure test(lambda a: print("You are in block %s" % a)) will work,

        not for me...

        lanx@nc10-ubuntu:~$ python Python 2.5.2 (r252:60911, Jan 20 2010, 23:16:55) [GCC 4.3.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> def rubyyielder(gen): ... def wrapped_gen(block): ... for elem in gen(): ... block(elem) ... return wrapped_gen ... >>> @rubyyielder ... def test(): ... print("In test") ... yield 1 ... print("back in test") ... yield 2 ... >>> test(lambda a: print("You are in block %s" % a)) File "<stdin>", line 1 test(lambda a: print("You are in block %s" % a)) ^ SyntaxError: invalid syntax

        I suppose the lamda syntax has more restrictions...

        > If you used a non-keyword such as "send" instead of "yield" you could do Evil and avoid the first decorator. This is left as an exercise.

        Simple, I can just port the semantic of my OP and let send execute the callback which is passed to @test.¹

        Cheers Rolf

        ( addicted to the Perl Programming Language)

        Update

        ¹) at second thought this would require a possibility to access the arguments of the caller. I suppose the caller is an object where arguments are accessible.

        Update

        deleted undiplomatic irony =)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1030852]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (4)
As of 2024-04-23 22:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found