Re: a Python person's experience with Ruby
In article <[EMAIL PROTECTED]>, Bruno Desthuilliers <[EMAIL PROTECTED]> wrote: > Lou Pecora a écrit : > > In article <[EMAIL PROTECTED]>, > > Bruno Desthuilliers <[EMAIL PROTECTED]> wrote: > > > > > >>>Thus: close; > >>>could replace close(); > > *Please* give proper attribution. I'd *never* suggest such a thing. I apologize. -- -- Lou Pecora -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
On Dec 9, 2007 5:11 AM, Arnaud Delobelle <[EMAIL PROTECTED]> wrote: > On Dec 9, 12:15 am, Bruno Desthuilliers > <[EMAIL PROTECTED]> wrote: > > Richard Jones a écrit : > > > > > > > > > Bruno Desthuilliers wrote: > > > > >>class A(object): > > >> @apply > > >> def a(): > > >> def fget(self): > > >> return self._a > > >> def fset(self, val): > > >> self._a = val > > >> return property(**locals()) > > >> def __init__(self): > > >> self.a = "foo" > > > > > That property setup seems overly complicated. As far as I can see, it only > > > avoids defining the setter in the class namespace, > > > > Yes. That's mosly the point. > > > > > yet is more complicated > > > and obfuscated to boot ;) > > > > Well, that's your POV, so what can I say ? It's indeed a bit hackish, > > and requires a couple minutes of attention the first time you see it. > > And you just have to learn it once !-) > > Perhaps 'return property(fget, fset)' would be easier to make sense of > than **locals() > > > Now I'd certainly prefer something like: > > > > class A(object): > > @propget > > def a(self): > > return self._a > > @propset > > def a(self, val): > > self._a = val > > > > But until there's something similar *builtin*, I'll stick to the @apply > > trick. > > At first sight, I like the look of this. Obviously I can't provide a > builtin implementation, but there's an easy way to achieve this. It > uses sys._getframe but there is no need to fiddle with metaclasses: > Something very like this will be in 3k, and I believe is also being backported to 2.6. See python-dev archives for more. -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
MonkeeSage a écrit : > On Dec 9, 6:23 pm, MonkeeSage <[EMAIL PROTECTED]> wrote: >> Hi Bruno, >> >> I think that we've been having a mainly "semantic" (pun intended) >> dispute. I think you're right, that we've been using the same words >> with different meanings. Fine. So we may have a chance to get out there !-) (snip) >> I would like to (try to) clarify a little about my use of wording. By >> "attribute" I was referring to a member of an object (*other than* >> toplevel). I was of course using "method" to refer to callable >> attributes (and I would use "function" for callable attributes bound >> to toplevel), and I was using "variable" to refer to non-callable >> attributes. By "tagging" I meant that attributes without a >> "tag" (e.g., __call__) are not included in the MRO for an object; they >> must be "tagged" as something other than a "variable". Nope. We've been thru the distinction between a callable attribute and a methodin another nearby thread, so won't come back on this. wrt/ mro, it's being used for *all* attributes. That is, the look up rule for an attribute is : 1. instance's __dict__ 2. class's __dict__ 3. all classes __dict__s in the class's mro NB : not taking __getattribute__ and __getattr__ hooks into account here. >> As for ruby, I think the opcodes will help me clarify... Not for me, sorry - my time to deal with my own ignorance !-) require 'parse_tree' >> => true ParseTree.translate(%q{ >> class A >> def foo >> "bar" >> end >> end >> A.new.foo}) >> >> => [:block, [:class, :A, nil, [:scope, [:defn, :foo, [:scope, [:block, >> [:args], [:str, "bar"]], [:call, [:call, >> [:const, :A], :new], :foo]] >> >> Notice that #new and #foo are both CALL ops. All attribute access is >> CALL (i.e., "method"). There really is no such thing as a non-callable >> "attribute" in ruby. For a definition of attribute being different from 'member variable'. But what we disagreed was more about the definitions of 'attribute' and 'callable' !-) >> Given this, I see the addition the instance variable also being an >> attribute as a *huge* difference between the ruby code and your >> initial example. An attribute can be named the same as an lval and >> return or set the value of the lval (e.g., @a), but it's no different >> from any other method. You still have both a member variable and an 'attribute'. And the member variable is stored in the instance, while the 'attribute' (that is, the getter and setter methods) are stored with the class. From this POV, this is the equivalent of the Python snippet using a property. >> But at the same time, I can see how my python example can be seen as >> *wildly* different (WTF?) as well. The WTF was about the class attribute. Did you try it with a mutable object instead of a string, and more than one instance ?-) >> Maybe there is no easy way to >> provide a true formally equivalent translation due to the >> implementation differences of the languages That's why I think the important point here is the semantic, not the implementation (while talking about the method/non-method distinction in Python is clearly about implementation). >> Anyhow, sorry for the confusion. You don't have to be sorry. We're both guilty (if guilty of anything) and honestly, I tend to be a bit on the nit-pick side, which sometimes doesn't help. > Ps. To answer a question you asked, "callable" objects don't generally > implement a #call method--just Proc objects and method references > [class Method instances] do, which even though they have a #call > method, aren't usually considered "callable" since you can't call them > directly--the #call method could as easily be named #run or #evaluate > or whatever. Accessing a name in ruby basically does something like: > VCALL name (== if parens on name like a() skip to call step, otherwise > check for LVAL in scope and return value if found, otherwise FCALL/ > CALL and return result). You can use the #define_method method to > create a new "callable." Thanks for the precisions. regards, -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
On Dec 9, 1:15 am, Bruno Desthuilliers <[EMAIL PROTECTED]> wrote: > Richard Jones a écrit : > > > > > Bruno Desthuilliers wrote: > > >>class A(object): > >> @apply > >> def a(): > >> def fget(self): > >> return self._a > >> def fset(self, val): > >> self._a = val > >> return property(**locals()) > >> def __init__(self): > >> self.a = "foo" > > > That property setup seems overly complicated. As far as I can see, it only > > avoids defining the setter in the class namespace, > > Yes. That's mosly the point. > > > yet is more complicated > > and obfuscated to boot ;) > > Well, that's your POV, so what can I say ? It's indeed a bit hackish, > and requires a couple minutes of attention the first time you see it. > And you just have to learn it once !-) > > Now I'd certainly prefer something like: > > class A(object): > @propget > def a(self): > return self._a > @propset > def a(self, val): > self._a = val > > But until there's something similar *builtin*, I'll stick to the @apply > trick. I like Guido's proposal for read/write properties. http://mail.python.org/pipermail/python-dev/2007-November/075182.html It works pretty well and is readable. -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
--- MonkeeSage <[EMAIL PROTECTED]> wrote: > On Dec 9, 6:23 pm, MonkeeSage <[EMAIL PROTECTED]> > wrote: > > Hi Bruno, > > > > I think that we've been having a mainly "semantic" > (pun intended) > > dispute. I think you're right, that we've been > using the same words > > with different meanings. > > I think Ruby and Python have lots of false cognates, or faux amis. > > > > But at the same time, I can see how my python > example can be seen as > > *wildly* different (WTF?) as well. Maybe there is > no easy way to > > provide a true formally equivalent translation due > to the > > implementation differences of the languages (or if > Saphir-Whorf is > > right, maybe we just can't think of it! ;) > > I think that there is an inherent difficulty in translation here. To give a metaphor, it's impossible, or at least very difficult, to explain, in French, how certain English phrases translate to French, without your French sounding a little English, or just downright wrong. And vice versa. Be a better friend, newshound, and know-it-all with Yahoo! Mobile. Try it now. http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
On Dec 9, 6:23 pm, MonkeeSage <[EMAIL PROTECTED]> wrote: > Hi Bruno, > > I think that we've been having a mainly "semantic" (pun intended) > dispute. I think you're right, that we've been using the same words > with different meanings. > > I would like to say firstly that I've been using python for a few > years now (about three I think), and I think I have a basic grasp of > the object system and so forth (e.g., I understood your example with > the apply decorator and properties). I read the docs when I first > started learning python (along with Fredrik Lundh's page about python > objects and more recently "call by object"). But I also own up to my > ignorance. I'm not a guru by any means. So you'll have to forgive me > if my ignorance has gotten in the way. I'll definitely re-read the > docs tonight. > > I would like to (try to) clarify a little about my use of wording. By > "attribute" I was referring to a member of an object (*other than* > toplevel). I was of course using "method" to refer to callable > attributes (and I would use "function" for callable attributes bound > to toplevel), and I was using "variable" to refer to non-callable > attributes. By "tagging" I meant that attributes without a > "tag" (e.g., __call__) are not included in the MRO for an object; they > must be "tagged" as something other than a "variable". > > As for ruby, I think the opcodes will help me clarify... > > >> require 'parse_tree' > => true > >> ParseTree.translate(%q{ > > class A > def foo > "bar" > end > end > A.new.foo}) > > => [:block, [:class, :A, nil, [:scope, [:defn, :foo, [:scope, [:block, > [:args], [:str, "bar"]], [:call, [:call, > [:const, :A], :new], :foo]] > > Notice that #new and #foo are both CALL ops. All attribute access is > CALL (i.e., "method"). There really is no such thing as a non-callable > "attribute" in ruby. Within the scope of a class (block, &c), there > can be non-callable members of course (LVAL), but "foo" can mean > either LVAL *or* FCALL, because there is no "tagging", it's just > whatever is in context and/or parsed first as a given type of object > (well there are a few other rules, but that's the main idea), with > "()" is a hint to help the parser when the expression is ambiguous: > > a = 1 > def a; 2; end > a # [:lval :a] == a = 1 > a() # [:fcall :a] == def ... > > Given this, I see the addition the instance variable also being an > attribute as a *huge* difference between the ruby code and your > initial example. An attribute can be named the same as an lval and > return or set the value of the lval (e.g., @a), but it's no different > from any other method. > > class A > def initialize; @a = "blah"; end > attr_reader :a > def cheese; @a; end # exactly equivalent > end > > But at the same time, I can see how my python example can be seen as > *wildly* different (WTF?) as well. Maybe there is no easy way to > provide a true formally equivalent translation due to the > implementation differences of the languages (or if Saphir-Whorf is > right, maybe we just can't think of it! ;) > > Anyhow, sorry for the confusion. > > Regards, > Jordan Ps. To answer a question you asked, "callable" objects don't generally implement a #call method--just Proc objects and method references [class Method instances] do, which even though they have a #call method, aren't usually considered "callable" since you can't call them directly--the #call method could as easily be named #run or #evaluate or whatever. Accessing a name in ruby basically does something like: VCALL name (== if parens on name like a() skip to call step, otherwise check for LVAL in scope and return value if found, otherwise FCALL/ CALL and return result). You can use the #define_method method to create a new "callable." Regards, Jordan -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
Hi Bruno, I think that we've been having a mainly "semantic" (pun intended) dispute. I think you're right, that we've been using the same words with different meanings. I would like to say firstly that I've been using python for a few years now (about three I think), and I think I have a basic grasp of the object system and so forth (e.g., I understood your example with the apply decorator and properties). I read the docs when I first started learning python (along with Fredrik Lundh's page about python objects and more recently "call by object"). But I also own up to my ignorance. I'm not a guru by any means. So you'll have to forgive me if my ignorance has gotten in the way. I'll definitely re-read the docs tonight. I would like to (try to) clarify a little about my use of wording. By "attribute" I was referring to a member of an object (*other than* toplevel). I was of course using "method" to refer to callable attributes (and I would use "function" for callable attributes bound to toplevel), and I was using "variable" to refer to non-callable attributes. By "tagging" I meant that attributes without a "tag" (e.g., __call__) are not included in the MRO for an object; they must be "tagged" as something other than a "variable". As for ruby, I think the opcodes will help me clarify... >> require 'parse_tree' => true >> ParseTree.translate(%q{ class A def foo "bar" end end A.new.foo }) => [:block, [:class, :A, nil, [:scope, [:defn, :foo, [:scope, [:block, [:args], [:str, "bar"]], [:call, [:call, [:const, :A], :new], :foo]] Notice that #new and #foo are both CALL ops. All attribute access is CALL (i.e., "method"). There really is no such thing as a non-callable "attribute" in ruby. Within the scope of a class (block, &c), there can be non-callable members of course (LVAL), but "foo" can mean either LVAL *or* FCALL, because there is no "tagging", it's just whatever is in context and/or parsed first as a given type of object (well there are a few other rules, but that's the main idea), with "()" is a hint to help the parser when the expression is ambiguous: a = 1 def a; 2; end a # [:lval :a] == a = 1 a() # [:fcall :a] == def ... Given this, I see the addition the instance variable also being an attribute as a *huge* difference between the ruby code and your initial example. An attribute can be named the same as an lval and return or set the value of the lval (e.g., @a), but it's no different from any other method. class A def initialize; @a = "blah"; end attr_reader :a def cheese; @a; end # exactly equivalent end But at the same time, I can see how my python example can be seen as *wildly* different (WTF?) as well. Maybe there is no easy way to provide a true formally equivalent translation due to the implementation differences of the languages (or if Saphir-Whorf is right, maybe we just can't think of it! ;) Anyhow, sorry for the confusion. Regards, Jordan -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
--- Bruno Desthuilliers <[EMAIL PROTECTED]> wrote: > Steve Howell a écrit : > (snip) > > > > Jordan and others, thanks for all your posts; I am > > learning a lot about both languages. > > > > This is what I've gathered so far. > > > > Python philosophy: > >passing around references to methods should be > > natural (i.e. my_binary_op = math.add) > >calling methods should be explicit (use parens) > >the use of setters/getters varies among Python > > programmers; properties, decorators, special > methods, > > etc. can be used judiciously to affect the > interface > > You can forget decorators here - the examples in > this thread were mostly > tricky ways to define properties. To be more > general, the Python way to > implement transparent computed attributes is to hook > into the lookup > mechanism, usually thru the descriptor protocol (the > property class > being one possible implementation), but also using > the __getattr__ / > __getattribute / __setattr__ hooks. > Ok, that makes sense. > > Ruby philosophy: > >a method itself should be callable without > parens > >you can get a reference to a chunk of code, but > > then you need a little extra syntax, beyond just a > > variable name and parens, to eventually call it > > (yield, &, call, etc.) > >when referring to methods, you can use :symbols > to > > name the method you're interested in without > actually > > calling it > > > > My personal experience: > > > (snip) > > > >I was surprised in Ruby by how seldom I really > pass > > references to methods around, > > This probably has to do with this nice feature named > 'blocks' !-) > Partly. It's also due to the fact that my experience so far in Ruby has mostly been writing code at the top layer of a fairly vanilla Rails MVC app, whereas in Python I've done a much wider variety of tasks. Be a better friend, newshound, and know-it-all with Yahoo! Mobile. Try it now. http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
Steve Howell a écrit : (snip) > > Jordan and others, thanks for all your posts; I am > learning a lot about both languages. > > This is what I've gathered so far. > > Python philosophy: >passing around references to methods should be > natural (i.e. my_binary_op = math.add) >calling methods should be explicit (use parens) >the use of setters/getters varies among Python > programmers; properties, decorators, special methods, > etc. can be used judiciously to affect the interface You can forget decorators here - the examples in this thread were mostly tricky ways to define properties. To be more general, the Python way to implement transparent computed attributes is to hook into the lookup mechanism, usually thru the descriptor protocol (the property class being one possible implementation), but also using the __getattr__ / __getattribute / __setattr__ hooks. > Ruby philosophy: >a method itself should be callable without parens >you can get a reference to a chunk of code, but > then you need a little extra syntax, beyond just a > variable name and parens, to eventually call it > (yield, &, call, etc.) >when referring to methods, you can use :symbols to > name the method you're interested in without actually > calling it > > My personal experience: > (snip) > >I was surprised in Ruby by how seldom I really pass > references to methods around, This probably has to do with this nice feature named 'blocks' !-) > but it is definitely > something I want to understand better. > -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
MonkeeSage a écrit : > On Dec 9, 1:58 pm, MonkeeSage <[EMAIL PROTECTED]> wrote: > > >> Sure. But as I understand, every attribute in python is a value, > > > sorry...*references* a value > So make it: 'reference an object' -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
MonkeeSage a écrit : > On Dec 8, 4:54 pm, Bruno Desthuilliers > <[EMAIL PROTECTED]> wrote: > >>MonkeeSage a écrit : >> >> >> >> >>>On Dec 8, 12:42 pm, Bruno Desthuilliers >>><[EMAIL PROTECTED]> wrote: >> MonkeeSage a écrit : >> >On Dec 7, 11:08 pm, Steve Howell <[EMAIL PROTECTED]> wrote: >> (snip) >> >>4) Ruby forces you to explicitly make attributes for >>instance variables. At first I found this clumsy, but >>I've gotten used to it, and I actually kind of like it >>in certain circumstances. >> >4.) Yeah, it's hard when learning ruby, especially if coming from >languages that distinguish between methods and attributes, >> which is not the case in Python >> >>>It is, I just wasn't absolutely precise (uh-oh, here comes the >>>semantics police! -- don't pass GO, don't collect $200, go strait to >>>jail!). Python *does* distinguish between instance/class vars and >>>instance/class methods. But in ruby no such distinction exists. >>>Accessing a "variable" in ruby == calling object.var. I.e., in ruby, >>>when you say "blah.x" that translates to "blah.send(:x)", whether :x >>>is a "variable" or a "method," since *everything* is a method. The >>>call model of ruby is more like smalltalk. >> >>I'm sorry to have to insist: Python doesn't distinguish between methods >>and attributes. Calling a method in Python is really 1/ looking up an >>attribute then 2/ applying the call operator on what the lookup eval'd >>to. As a matter of fact, you can stop at the first step, and you'll have >>a reference to whatever the lookup mechanism yielded for the given >>attribute name on the given object. FWIW, Python's functions are plain >>objects, and when used as attributes are stored in the same place as any >>other attribute. > > > Except that pthon does differentiate, as python variables are not > callable, I beg your pardon ? Python 2.4.3 (#1, Mar 12 2007, 23:32:01) [GCC 3.3.4 20040623 (Gentoo Linux 3.3.4-r1, ssp-3.3.2-2, pie-8.7.6)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> class Toto(object): ... def test(self): print self ... def __call__(self): print self ... >>> def boo(): print "boo" ... >>> Toto >>> # Toto is a variable. Is it callable ? ... >>> callable(Toto) True >>> Toto() <__main__.Toto object at 0x4033492c> >>> t = Toto() >>> t <__main__.Toto object at 0x403344cc> >>> # t is a variable. Is it callable ? ... callable(t) True >>> t() <__main__.Toto object at 0x403344cc> >>> t.test > >>> # t.test is a variable. is it callable ? ... callable(t.test) True >>> t.test() <__main__.Toto object at 0x403344cc> >>> t.foo Traceback (most recent call last): File "", line 1, in ? AttributeError: 'Toto' object has no attribute 'foo' >>> t.foo = boo >>> t.foo >>> # t.foo is a variable. Is it callable ? ... callable(t.foo) True >>> t.foo() boo >>> > whereas everything in ruby is callable. blah.a in ruby means > blah.send(:a). Ok, I see where the problem is. We definitively don't have the same definition of 'callable'. In Python, a callable is an object that can be called - that is, you can apply the call operator to it. You'd better get use to this definition when talking about Python, FWIW !-) What you say is that in Ruby, you're *always* going thru a method call when accessing an attribute (from outside at least). The fact is that Ruby is built on 'true' (ie: à la Smalltalk) message passing, when Python is built on the attribute lookup operator and the call operator. As I said, while Python and Ruby have similarities, they are built on totally disjoint object models - different ways to get at the same thing... > Which is why you need an accessor to get at instance > variables, since as variables they exist in the scope scope of the > class, but they are not callable so they are not attributes of the > instance. I would certainly not define it that way, but anyway... >to get used >to thinking of "a.a" and "a.a=" as method calls and defining accessors >for those methods (or using one of the attr_* keywords) in the class >body. >> Python has an equivalent support for computed attributes, using property or a custom descriptors. While it's a bit lower-level than Ruby, it's still quite easy to use and IMHO a bit more powerful. >> >The equivalent python idiom is something like: >> >class A: > __a = "foo" > def __init__(self): > self.a = A.__a >> WTF ??? >> >Which roughly translates to this in ruby: >> >class A > attr_accessor :a > def initialize > @a = "foo" > end >end >> The Python translation of the above Ruby snippet is actually way more simple: >> class A(object): def __init__(self): self.a = "foo" >> >>>Not really. >> >>Yes, really. Sorry to have to insist, but... >> >> >>>In ruby an ivar is accessible within the class *only*, but >>>not from without (like a mangled python class var), un
Re: a Python person's experience with Ruby
On Dec 9, 3:10 pm, I V <[EMAIL PROTECTED]> wrote: > On Sun, 09 Dec 2007 11:58:05 -0800, MonkeeSage wrote: > > class A > > attr_accessor :a # == self.a, > ># accessible to instances of A > > def initialize > > @a = "foo" # A.__a > ># only accessible from class scope of A > > end > > end > > > Once again, there is no such thing as an attribute that is not a method > > in ruby, and there is no such thing as setting an *attribute* ("=" is a > > method also). You're trying to *re-implement* rubys mechanism in python > > in your example, but in pythons mechanism, all attributes already have > > built-in getter/setter. So the correct analogy is a variable that is > > accessible from within the classes scope only (A.__a), and then exposed > > to instances through an attribute (self.a). Your example leaves out a > > variable accessible only from within the scope of the class, and adds a > > new attribute accessible from the instance (_a). > > Either I'm not understanding you, or you're not understanding what A.__a > means in python. A.__a is a class attribute, not an instance attribute - > it's equivalent to @@a in ruby, not @a. I said previously that A.__a is a class variable. Since I was only using it to show that @a is not exposed as an attribute, I just used A.__a, but you're right, it would have been better to use self.__a. > If I understand what you're > saying, a better python example to make your point might be: > > class A(object): > def __init__(self): > self.__a = "foo" # equivalent to @a > self.a = self.__a # exposes self.__a Thanks. > Except that this only allows you to access '__a' via the exposed > attribute 'a', not bind it to a new object. If you do: > > inst = A() > inst.a = "bar" > > you don't modify inst.__a, unlike the following ruby code, which does > modify @a . > > inst = A.new > inst.a = "bar" I understand. That's why I said it was a rough translation of the ruby code. I was only trying to say that it's strange when learning ruby, to get your head around the idea that instance (and class) variables are not attributes; that all attributes are callable. The example was merely to demonstrate the distinction between instance method and instance variable in ruby. The python isn't supposed to have the exact same behavior, just a similar semantic. Regards, Jordan -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
On Sun, 09 Dec 2007 11:58:05 -0800, MonkeeSage wrote: > class A > attr_accessor :a # == self.a, ># accessible to instances of A > def initialize > @a = "foo" # A.__a ># only accessible from class scope of A > end > end > > Once again, there is no such thing as an attribute that is not a method > in ruby, and there is no such thing as setting an *attribute* ("=" is a > method also). You're trying to *re-implement* rubys mechanism in python > in your example, but in pythons mechanism, all attributes already have > built-in getter/setter. So the correct analogy is a variable that is > accessible from within the classes scope only (A.__a), and then exposed > to instances through an attribute (self.a). Your example leaves out a > variable accessible only from within the scope of the class, and adds a > new attribute accessible from the instance (_a). Either I'm not understanding you, or you're not understanding what A.__a means in python. A.__a is a class attribute, not an instance attribute - it's equivalent to @@a in ruby, not @a. If I understand what you're saying, a better python example to make your point might be: class A(object): def __init__(self): self.__a = "foo" # equivalent to @a self.a = self.__a # exposes self.__a Except that this only allows you to access '__a' via the exposed attribute 'a', not bind it to a new object. If you do: inst = A() inst.a = "bar" you don't modify inst.__a, unlike the following ruby code, which does modify @a . inst = A.new inst.a = "bar" -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
--- MonkeeSage <[EMAIL PROTECTED]> wrote: > > Not just callable, but interchangeable. My point was > that in ruby, if > you use a block or a lambda as a HOF, you have to > use #call / #[] / > yield keyword on it to call it. > > def foo(a) > puts a > end > bar = lambda { | a | puts a } > > # these do the same thing > [1,2,3].each(&bar) > [1,2,3].each(&method(:foo)) > > That's not to say it's better than python (like I > said, I personally I > like pythons referencing / calling convention a > little better), it's > just that since Proc objects already have that call > syntax in ruby, > making method references use it also allows them to > be interchanged (w/ > o having to do method(:foo).to_proc). > Jordan and others, thanks for all your posts; I am learning a lot about both languages. This is what I've gathered so far. Python philosophy: passing around references to methods should be natural (i.e. my_binary_op = math.add) calling methods should be explicit (use parens) the use of setters/getters varies among Python programmers; properties, decorators, special methods, etc. can be used judiciously to affect the interface Ruby philosophy: a method itself should be callable without parens you can get a reference to a chunk of code, but then you need a little extra syntax, beyond just a variable name and parens, to eventually call it (yield, &, call, etc.) when referring to methods, you can use :symbols to name the method you're interested in without actually calling it My personal experience: Even after doing lots of Python, I occasionally got bitten by the pitfall of omitting the parens when I meant to call something, but it was never major pain. (I never made the opposite mistake, in case you're wondering.) Despite the pitfall above, I always liked the tradeoff that Python gave me more natural syntax for passing around methods. (And, more fundamentally, I like the Python notion of binding "general" things to a name.) As somebody just starting to use Ruby, I actually like omitting parens in method calls, which I view as the more common case. I admit some cost here, though, in simple churn of the code due to the fact that some people like having parens for aesthetic reasons. I was surprised in Ruby by how seldom I really pass references to methods around, but it is definitely something I want to understand better. I hope this adds a little perspective, and please feel free to correct me in cases where I'm either imprecise or just flat out wrong. Never miss a thing. Make Yahoo your home page. http://www.yahoo.com/r/hs -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
On Dec 9, 1:58 pm, MonkeeSage <[EMAIL PROTECTED]> wrote: > Sure. But as I understand, every attribute in python is a value, sorry...*references* a value -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
On Dec 8, 4:54 pm, Bruno Desthuilliers <[EMAIL PROTECTED]> wrote: > MonkeeSage a écrit : > > > > > On Dec 8, 12:42 pm, Bruno Desthuilliers > > <[EMAIL PROTECTED]> wrote: > > >>MonkeeSage a écrit : > > >>>On Dec 7, 11:08 pm, Steve Howell <[EMAIL PROTECTED]> wrote: > > >>(snip) > > 4) Ruby forces you to explicitly make attributes for > instance variables. At first I found this clumsy, but > I've gotten used to it, and I actually kind of like it > in certain circumstances. > > >>>4.) Yeah, it's hard when learning ruby, especially if coming from > >>>languages that distinguish between methods and attributes, > > >>which is not the case in Python > > > It is, I just wasn't absolutely precise (uh-oh, here comes the > > semantics police! -- don't pass GO, don't collect $200, go strait to > > jail!). Python *does* distinguish between instance/class vars and > > instance/class methods. But in ruby no such distinction exists. > > Accessing a "variable" in ruby == calling object.var. I.e., in ruby, > > when you say "blah.x" that translates to "blah.send(:x)", whether :x > > is a "variable" or a "method," since *everything* is a method. The > > call model of ruby is more like smalltalk. > > I'm sorry to have to insist: Python doesn't distinguish between methods > and attributes. Calling a method in Python is really 1/ looking up an > attribute then 2/ applying the call operator on what the lookup eval'd > to. As a matter of fact, you can stop at the first step, and you'll have > a reference to whatever the lookup mechanism yielded for the given > attribute name on the given object. FWIW, Python's functions are plain > objects, and when used as attributes are stored in the same place as any > other attribute. Except that pthon does differentiate, as python variables are not callable, whereas everything in ruby is callable. blah.a in ruby means blah.send(:a). Which is why you need an accessor to get at instance variables, since as variables they exist in the scope scope of the class, but they are not callable so they are not attributes of the instance. > >>>to get used > >>>to thinking of "a.a" and "a.a=" as method calls and defining accessors > >>>for those methods (or using one of the attr_* keywords) in the class > >>>body. > > >>Python has an equivalent support for computed attributes, using property > >>or a custom descriptors. While it's a bit lower-level than Ruby, it's > >>still quite easy to use and IMHO a bit more powerful. > > >>>The equivalent python idiom is something like: > > >>>class A: > >>> __a = "foo" > >>> def __init__(self): > >>>self.a = A.__a > > >>WTF ??? > > >>>Which roughly translates to this in ruby: > > >>>class A > >>> attr_accessor :a > >>> def initialize > >>>@a = "foo" > >>> end > >>>end > > >>The Python translation of the above Ruby snippet is actually way more > >>simple: > > >>class A(object): > >> def __init__(self): > >> self.a = "foo" > > > Not really. > > Yes, really. Sorry to have to insist, but... > > > In ruby an ivar is accessible within the class *only*, but > > not from without (like a mangled python class var), unless you declare > > an accessor (or write the accessor methods yourself). > > Your Ruby snippets uses attr_accessor, which gives direct, uncontrolled > read/write access to the attribute. So I maintain that the *exact* > semantic equivalent in Python of your Ruby snippet is a plain attribute. > > > So my example is > > closer, and is not a WTF, if you know how ruby works. > > I know enough about Ruby to understand this snippet, and enough about > Python to tell your Python example is a WTF. > > FWIW, your Python snippet ends up doing the same thing as mine - that > is, it defines a plain instance attribute named 'a' - but uses a > reference to class attribute instead of a string literal as the initial > value of the instance attribute. Since Python strings are immutable, the > final result is the same wrt/ the instance attribute - it's just overly > complicated, hence the WTF label. > > OTHO, your Python code also defines a class attribute which doesn't > exist in the Ruby snippet. Mine doesn't imply any class attribute. So my > Python translation is way closer to the Ruby original !-) > > If you what you had in mind was an example of a computed attribute, > here's the correct code: > > class A(object): >@apply >def a(): > def fget(self): >return self._a > def fset(self, val): >self._a = val > return property(**locals()) >def __init__(self): > self.a = "foo" > > Now since we're just getting/setting the attribute, all these > indirection levels are totally useless, so in such a case we just use a > plain attribute. So my first exemple (plain attribute) is effectively > the *exact* semantic equivalent of your Ruby snippet. CQFD. No, it's not at all. class A attr_accessor :a # == self.a, # accessible to instances of A def initialize @a = "foo" # A.__a
Re: a Python person's experience with Ruby
Lou Pecora a écrit : > In article <[EMAIL PROTECTED]>, > Bruno Desthuilliers <[EMAIL PROTECTED]> wrote: > > >>>Thus: close; >>>could replace close(); *Please* give proper attribution. I'd *never* suggest such a thing. > > Wouldn't this give an ambiguity? > > afcn=close # make an "alias" to the close function > val=close() # set val to the return value of the close function > The point of Colin (who was the one making this suggestion) was that parens could be omitted if there was no LHS. -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
After starting this discussion thread, I found the link below: http://www.b-list.org/weblog/2006/jun/18/lets-talk-about-python-and-ruby/ If you're like me--struggling to learn Ruby while having Python as your primary point of reference--you might find some of the points informative. I suspect vice versa as well. Be a better friend, newshound, and know-it-all with Yahoo! Mobile. Try it now. http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
In article <[EMAIL PROTECTED]>, Bruno Desthuilliers <[EMAIL PROTECTED]> wrote: > > Thus: close; > > could replace close(); Wouldn't this give an ambiguity? afcn=close # make an "alias" to the close function val=close() # set val to the return value of the close function -- -- Lou Pecora -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
On Dec 9, 12:15 am, Bruno Desthuilliers <[EMAIL PROTECTED]> wrote: > Richard Jones a écrit : > > > > > Bruno Desthuilliers wrote: > > >>class A(object): > >> @apply > >> def a(): > >> def fget(self): > >> return self._a > >> def fset(self, val): > >> self._a = val > >> return property(**locals()) > >> def __init__(self): > >> self.a = "foo" > > > That property setup seems overly complicated. As far as I can see, it only > > avoids defining the setter in the class namespace, > > Yes. That's mosly the point. > > > yet is more complicated > > and obfuscated to boot ;) > > Well, that's your POV, so what can I say ? It's indeed a bit hackish, > and requires a couple minutes of attention the first time you see it. > And you just have to learn it once !-) Perhaps 'return property(fget, fset)' would be easier to make sense of than **locals() > Now I'd certainly prefer something like: > > class A(object): > @propget > def a(self): > return self._a > @propset > def a(self, val): > self._a = val > > But until there's something similar *builtin*, I'll stick to the @apply > trick. At first sight, I like the look of this. Obviously I can't provide a builtin implementation, but there's an easy way to achieve this. It uses sys._getframe but there is no need to fiddle with metaclasses: from sys import _getframe def _makeprop(frame, name, **d): p = frame.f_locals.get(name, None) args = {} if isinstance(p, property): args = dict(fget=p.fget, fset=p.fset, fdel=p.fdel, doc=p.__doc__) args.update(d) return property(**args) def propget(f): return _makeprop(_getframe(1), f.__name__, fget=f) def propset(f): return _makeprop(_getframe(1), f.__name__, fset=f) def propdel(f): return _makeprop(_getframe(1), f.__name__, fdel=f) if __name__ == '__main__': class Foo(object): a = property(doc="mod10 attribute") @propget def a(self): return self._a @propset def a(self, a): self._a = a % 10 @propdel def a(self): del self._a f = Foo() f.a = 42 assert f.a == 42 % 10 -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
On Dec 8, 8:56 pm, Steve Howell <[EMAIL PROTECTED]> wrote: > --- Bruno Desthuilliers > > <[EMAIL PROTECTED]> wrote: > > Colin J. Williams a écrit : > > > I'm not sure that I like add 3, 5, 7 > > > > but it would be nice to be able to drop the > > parentheses > > > when no argument is required. > > > > Thus: close; > > > could replace close(); > > > This just could not work given Python's object > > model. The parens > > actually *are* the call operator. > > I mostly agree with you, but in the specific use case > of having just a single token on a line, you could > argue that Python could DWIM on calling an object if > the object is callable, since otherwise it's just a > no-op. Argh! I smell context sensitive semantics which is the road to language design hell. Fortunately this hell is already occupied by Perl and Larry Wall is a charming and funky guy. You know what look for. -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
Richard Jones a écrit : > Bruno Desthuilliers wrote: > >>class A(object): >> @apply >> def a(): >> def fget(self): >> return self._a >> def fset(self, val): >> self._a = val >> return property(**locals()) >> def __init__(self): >> self.a = "foo" > > > That property setup seems overly complicated. As far as I can see, it only > avoids defining the setter in the class namespace, Yes. That's mosly the point. > yet is more complicated > and obfuscated to boot ;) Well, that's your POV, so what can I say ? It's indeed a bit hackish, and requires a couple minutes of attention the first time you see it. And you just have to learn it once !-) Now I'd certainly prefer something like: class A(object): @propget def a(self): return self._a @propset def a(self, val): self._a = val But until there's something similar *builtin*, I'll stick to the @apply trick. -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
--- Richard Jones <[EMAIL PROTECTED]> wrote: > > class A(object): > def set_a(self, value): > self._a = value > a = property(lambda self: self._a, set_a) > > Note that this differs from a regular attribute > because "a" is not deletable > from instances (the property defines no deleter). > The use case I was actually considering actually doesn't require much magic in either language. I commonly want to write code like this: e = Employee('jim', 'accounting', 50) print e.name print e.department print e.salary e.update_salary(percent=.10) e.update_salary(percent=.5) I want the name, department, and salary always exposed to me. But suppose in Employee's innards, it keeps a cache of the number of raises Jim has been given, and this cache is very implementation-sensitive. The way I achieve this is different in each language: 1) In Python I get name, department, and salary exposed for free, but I need to make a more conscious decision to hide e.compensation_tracker, which I do by renaming it to e.__compensation_tracker. 2) In Ruby I get compensation_tracker fully hidden/encapsulated for free, but I have to make a more conscious decision to expose name, department, and salary, which I get by saying: attr_reader :name, :department, :salary Obviously, things can get a lot more complicated than this scenario, and I think both languages are pretty flexible, but flexible in a different way. Be a better friend, newshound, and know-it-all with Yahoo! Mobile. Try it now. http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
--- Bruno Desthuilliers > > > Another aspect of Ruby is that the final > expression > > evaluated in a method actually gets returned as > the > > result of a method, > > Unless there's an explict return before... > > > which has further implications on > > whether "close" is simply evaluated or called. > > I'm sorry but I'm not sure I get the point here. I'm just giving another example that the following seemingly innocuous line of code has lots of side effects in both languages, but the two languages differ: transaction.finish # last line in method 1) Some one new to Python might be surprised that finish never gets invoked. 2) Some new to Ruby might be surprised that the command above might actually cause the enclosing method to return a non-nil value. For this code: return table.get_apples # last line of get_getter() 1) Some one new to Python might be surprised to see this code when get_apples is not explicitly written in MyTable. 2) Some one new to Ruby might be surprised that get_getter()() does not work as expected. Never miss a thing. Make Yahoo your home page. http://www.yahoo.com/r/hs -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
Bruno Desthuilliers wrote: > class A(object): >@apply >def a(): > def fget(self): >return self._a > def fset(self, val): >self._a = val > return property(**locals()) >def __init__(self): > self.a = "foo" That property setup seems overly complicated. As far as I can see, it only avoids defining the setter in the class namespace, yet is more complicated and obfuscated to boot ;) class A(object): def set_a(self, value): self._a = value a = property(lambda self: self._a, set_a) Note that this differs from a regular attribute because "a" is not deletable from instances (the property defines no deleter). Richard -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
Steve Howell a écrit : > --- Bruno Desthuilliers > <[EMAIL PROTECTED]> wrote: > > >>Colin J. Williams a écrit : >> >>>I'm not sure that I like add 3, 5, 7 >>> >>>but it would be nice to be able to drop the >> >>parentheses >> >>>when no argument is required. >>> >>>Thus: close; >>>could replace close(); >> >>This just could not work given Python's object >>model. The parens >>actually *are* the call operator. >> > > > I mostly agree with you, but in the specific use case > of having just a single token on a line, you could > argue that Python could DWIM on calling an object if > the object is callable, since otherwise it's just a > no-op. It's not. If the name is not defined, it raises an exception (either a NameError or an AttributeError). And if the name resolves to a computed attribute, the getter for this computed attribute will be invoked - with possible side effects. > I think the argument against doing that is > more based on explicit-vs.-implicit principle versus > actual constraints of the object model. I'd say that the object model being the work of a strong proponent of the explicit-vs.-implicit principle, it's probably another chicken-and-egg problem - so we are both right here !-) > Another aspect of Ruby is that the final expression > evaluated in a method actually gets returned as the > result of a method, Unless there's an explict return before... > which has further implications on > whether "close" is simply evaluated or called. I'm sorry but I'm not sure I get the point here. -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
MonkeeSage a écrit : > On Dec 8, 12:42 pm, Bruno Desthuilliers > <[EMAIL PROTECTED]> wrote: > >>MonkeeSage a écrit : >> >> >>>On Dec 7, 11:08 pm, Steve Howell <[EMAIL PROTECTED]> wrote: >> >>(snip) >> 4) Ruby forces you to explicitly make attributes for instance variables. At first I found this clumsy, but I've gotten used to it, and I actually kind of like it in certain circumstances. >>> >>>4.) Yeah, it's hard when learning ruby, especially if coming from >>>languages that distinguish between methods and attributes, >> >>which is not the case in Python > > > It is, I just wasn't absolutely precise (uh-oh, here comes the > semantics police! -- don't pass GO, don't collect $200, go strait to > jail!). Python *does* distinguish between instance/class vars and > instance/class methods. But in ruby no such distinction exists. > Accessing a "variable" in ruby == calling object.var. I.e., in ruby, > when you say "blah.x" that translates to "blah.send(:x)", whether :x > is a "variable" or a "method," since *everything* is a method. The > call model of ruby is more like smalltalk. I'm sorry to have to insist: Python doesn't distinguish between methods and attributes. Calling a method in Python is really 1/ looking up an attribute then 2/ applying the call operator on what the lookup eval'd to. As a matter of fact, you can stop at the first step, and you'll have a reference to whatever the lookup mechanism yielded for the given attribute name on the given object. FWIW, Python's functions are plain objects, and when used as attributes are stored in the same place as any other attribute. > >>>to get used >>>to thinking of "a.a" and "a.a=" as method calls and defining accessors >>>for those methods (or using one of the attr_* keywords) in the class >>>body. >> >>Python has an equivalent support for computed attributes, using property >>or a custom descriptors. While it's a bit lower-level than Ruby, it's >>still quite easy to use and IMHO a bit more powerful. >> >> >>>The equivalent python idiom is something like: >> >>>class A: >>> __a = "foo" >>> def __init__(self): >>>self.a = A.__a >> >>WTF ??? >> >> >>>Which roughly translates to this in ruby: >> >>>class A >>> attr_accessor :a >>> def initialize >>>@a = "foo" >>> end >>>end >> >>The Python translation of the above Ruby snippet is actually way more >>simple: >> >>class A(object): >> def __init__(self): >> self.a = "foo" >> > > Not really. Yes, really. Sorry to have to insist, but... > In ruby an ivar is accessible within the class *only*, but > not from without (like a mangled python class var), unless you declare > an accessor (or write the accessor methods yourself). Your Ruby snippets uses attr_accessor, which gives direct, uncontrolled read/write access to the attribute. So I maintain that the *exact* semantic equivalent in Python of your Ruby snippet is a plain attribute. > So my example is > closer, and is not a WTF, if you know how ruby works. I know enough about Ruby to understand this snippet, and enough about Python to tell your Python example is a WTF. FWIW, your Python snippet ends up doing the same thing as mine - that is, it defines a plain instance attribute named 'a' - but uses a reference to class attribute instead of a string literal as the initial value of the instance attribute. Since Python strings are immutable, the final result is the same wrt/ the instance attribute - it's just overly complicated, hence the WTF label. OTHO, your Python code also defines a class attribute which doesn't exist in the Ruby snippet. Mine doesn't imply any class attribute. So my Python translation is way closer to the Ruby original !-) If you what you had in mind was an example of a computed attribute, here's the correct code: class A(object): @apply def a(): def fget(self): return self._a def fset(self, val): self._a = val return property(**locals()) def __init__(self): self.a = "foo" Now since we're just getting/setting the attribute, all these indirection levels are totally useless, so in such a case we just use a plain attribute. So my first exemple (plain attribute) is effectively the *exact* semantic equivalent of your Ruby snippet. CQFD. >>>1.) I also found python's style of method referencing to be a lot more >>>intuitive than using something like ruby's "m = method('foo'); >>>m.call('bar')" to get a reference to foo() and call it. It's alot >>>cleaner to say "m = foo; m('bar')", imo. But this goes back to the >>>omitting parens thing, which makes it impossible to do it that way in >>>ruby. >> >>Yeps. This is where the real and fundamental difference between Ruby and >>Python becomes evident. Both have support for transparent computed >>attributes, but the way it's implemented is totally different - in Ruby, >>by not having a call operator at all (I mean, the parens), in Python by >>having both an explicit call operator and an expli
Re: a Python person's experience with Ruby
On Sat, 08 Dec 2007 11:23:57 -0800, MonkeeSage wrote: >> > The equivalent python idiom is something like: >> >> > class A: >> > __a = "foo" >> > def __init__(self): >> > self.a = A.__a [...] >> > Which roughly translates to this in ruby: >> >> > class A >> > attr_accessor :a >> > def initialize >> > @a = "foo" >> > end >> > end [...] > Not really. In ruby an ivar is accessible within the class *only*, but > not from without (like a mangled python class var), unless you declare > an accessor (or write the accessor methods yourself). So my example is > closer, and is not a WTF, if you know how ruby works. In your python example, the class attribute is mangled, but the instance attribute isn't, whereas your ruby code has no class attribute, and an instance attribute that isn't (directly) accessible outside the class. The equivalent in python would involve a mangled instance attribute, like: class A(object): def __init__(self): self.__a = "foo" def get_a(self): return self.__a def set_a(self, val): self.__a = val a = property(get_a, set_a) -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
--- Bruno Desthuilliers <[EMAIL PROTECTED]> wrote: > Colin J. Williams a écrit : > > I'm not sure that I like add 3, 5, 7 > > > > but it would be nice to be able to drop the > parentheses > > when no argument is required. > > > > Thus: close; > > could replace close(); > > This just could not work given Python's object > model. The parens > actually *are* the call operator. > I mostly agree with you, but in the specific use case of having just a single token on a line, you could argue that Python could DWIM on calling an object if the object is callable, since otherwise it's just a no-op. I think the argument against doing that is more based on explicit-vs.-implicit principle versus actual constraints of the object model. Another aspect of Ruby is that the final expression evaluated in a method actually gets returned as the result of a method, which has further implications on whether "close" is simply evaluated or called. Never miss a thing. Make Yahoo your home page. http://www.yahoo.com/r/hs -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
On Dec 8, 12:42 pm, Bruno Desthuilliers <[EMAIL PROTECTED]> wrote: > MonkeeSage a écrit : > > > On Dec 7, 11:08 pm, Steve Howell <[EMAIL PROTECTED]> wrote: > > (snip) > >> 4) Ruby forces you to explicitly make attributes for > >> instance variables. At first I found this clumsy, but > >> I've gotten used to it, and I actually kind of like it > >> in certain circumstances. > > 4.) Yeah, it's hard when learning ruby, especially if coming from > > languages that distinguish between methods and attributes, > > which is not the case in Python It is, I just wasn't absolutely precise (uh-oh, here comes the semantics police! -- don't pass GO, don't collect $200, go strait to jail!). Python *does* distinguish between instance/class vars and instance/class methods. But in ruby no such distinction exists. Accessing a "variable" in ruby == calling object.var. I.e., in ruby, when you say "blah.x" that translates to "blah.send(:x)", whether :x is a "variable" or a "method," since *everything* is a method. The call model of ruby is more like smalltalk. > > to get used > > to thinking of "a.a" and "a.a=" as method calls and defining accessors > > for those methods (or using one of the attr_* keywords) in the class > > body. > > Python has an equivalent support for computed attributes, using property > or a custom descriptors. While it's a bit lower-level than Ruby, it's > still quite easy to use and IMHO a bit more powerful. > > > The equivalent python idiom is something like: > > > class A: > > __a = "foo" > > def __init__(self): > > self.a = A.__a > > WTF ??? > > > Which roughly translates to this in ruby: > > > class A > > attr_accessor :a > > def initialize > > @a = "foo" > > end > > end > > The Python translation of the above Ruby snippet is actually way more > simple: > > class A(object): >def __init__(self): > self.a = "foo" > > > Python: Not really. In ruby an ivar is accessible within the class *only*, but not from without (like a mangled python class var), unless you declare an accessor (or write the accessor methods yourself). So my example is closer, and is not a WTF, if you know how ruby works. > > 1.) I also found python's style of method referencing to be a lot more > > intuitive than using something like ruby's "m = method('foo'); > > m.call('bar')" to get a reference to foo() and call it. It's alot > > cleaner to say "m = foo; m('bar')", imo. But this goes back to the > > omitting parens thing, which makes it impossible to do it that way in > > ruby. > > Yeps. This is where the real and fundamental difference between Ruby and > Python becomes evident. Both have support for transparent computed > attributes, but the way it's implemented is totally different - in Ruby, > by not having a call operator at all (I mean, the parens), in Python by > having both an explicit call operator and an explicit protocol for > computed attributes (the descriptor protocol). Not to say one is better > than the other, but that while both languages have similar features > (and, at first look, similar syntaxes), they really have totally > different object models. Yes and no. I'll leave it at that. If you want to know more, do your homework. :P > > Though, ruby does allow some interesting things by having it > > that way, e.g., letting you substitute a Proc object (e.g., a block or > > lambda) for a method reference transparently. > > Care to give an example ? I don't have enough working experience with > Ruby to be sure I understand what you mean here. For example, any place expecting a foo (method reference), can be exchanged with a { "bar" } block or a lambda { "baz" }. > > 2.) I also find layout to be a nice feature. And since I've recently > > been using Haskell, it has only re-inforced that opinion. But when I > > first started using python, I got bitten by IndentationError quite > > often. And I kept wanting to type some closing symbol, heh. ;) > > The nice thing with Python is that it lets you use the closing symbol > you want, as long as you prefix it with a '#' !-) LOL. Well, yes, I used to do that, but I got over that irrational urge. ;) Regards, Jordan -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
Colin J. Williams a écrit : > Steve Howell wrote:> > Thanks for the interesting comparison. > > [snip] > >> 3) I actually like being able to omit parentheses in >> method definitions and method calls. In Ruby you can >> express "add(3,5,7)" as both "add(3,5,7)" and "add 3, >> 5, 7." The latter syntax is obviously more error >> prone, but I don't think I've ever actually gotten bit >> by it, and the code appears more clean to me. >> > [snip] > > I'm not sure that I like add 3, 5, 7 > > but it would be nice to be able to drop the parentheses > when no argument is required. > > Thus: close; > could replace close(); This just could not work given Python's object model. The parens actually *are* the call operator. -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
MonkeeSage a écrit : > On Dec 7, 11:08 pm, Steve Howell <[EMAIL PROTECTED]> wrote: > (snip) >> 4) Ruby forces you to explicitly make attributes for >> instance variables. At first I found this clumsy, but >> I've gotten used to it, and I actually kind of like it >> in certain circumstances. > 4.) Yeah, it's hard when learning ruby, especially if coming from > languages that distinguish between methods and attributes, which is not the case in Python > to get used > to thinking of "a.a" and "a.a=" as method calls and defining accessors > for those methods (or using one of the attr_* keywords) in the class > body. Python has an equivalent support for computed attributes, using property or a custom descriptors. While it's a bit lower-level than Ruby, it's still quite easy to use and IMHO a bit more powerful. > The equivalent python idiom is something like: > > class A: > __a = "foo" > def __init__(self): > self.a = A.__a WTF ??? > Which roughly translates to this in ruby: > > class A > attr_accessor :a > def initialize > @a = "foo" > end > end The Python translation of the above Ruby snippet is actually way more simple: class A(object): def __init__(self): self.a = "foo" > Python: > > 1.) I also found python's style of method referencing to be a lot more > intuitive than using something like ruby's "m = method('foo'); > m.call('bar')" to get a reference to foo() and call it. It's alot > cleaner to say "m = foo; m('bar')", imo. But this goes back to the > omitting parens thing, which makes it impossible to do it that way in > ruby. Yeps. This is where the real and fundamental difference between Ruby and Python becomes evident. Both have support for transparent computed attributes, but the way it's implemented is totally different - in Ruby, by not having a call operator at all (I mean, the parens), in Python by having both an explicit call operator and an explicit protocol for computed attributes (the descriptor protocol). Not to say one is better than the other, but that while both languages have similar features (and, at first look, similar syntaxes), they really have totally different object models. > Though, ruby does allow some interesting things by having it > that way, e.g., letting you substitute a Proc object (e.g., a block or > lambda) for a method reference transparently. Care to give an example ? I don't have enough working experience with Ruby to be sure I understand what you mean here. > 2.) I also find layout to be a nice feature. And since I've recently > been using Haskell, it has only re-inforced that opinion. But when I > first started using python, I got bitten by IndentationError quite > often. And I kept wanting to type some closing symbol, heh. ;) The nice thing with Python is that it lets you use the closing symbol you want, as long as you prefix it with a '#' !-) -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
I have been waiting for something like this! Thanks! On Dec 8, 2007 6:08 AM, Steve Howell <[EMAIL PROTECTED]> wrote: > Python is my favorite programming language. I've used > it as my primary language for about six years now, > including four years of using it full-time in my day > job. Three months ago I decided to take a position > with a team that does a lot of things very well, but > they don't use Python. We use Ruby instead. I'd like > to share my observations about Ruby, because I think > they say important things about Python, which has been > my frame of reference. > > First of all, I actually enjoy programming in Ruby. > Although I'm still fairly early on the learning curve, > I feel like I've achieved basic fluency, and it > generally stays out of the way. > > (A quick disclaimer is that some of the observations I > make about Ruby may simply reflect my ignorance about > the language. I'm still learning it.) > > The thing that I like least about Ruby is its > "require" mechanism. Basically, when you do "require" > in Ruby, it sort of pollutes your namespace. I much > prefer Python's explicitness. > > Some surprising things that I like about Ruby: > > 1) It has the Perlish natural language syntax of > "raise 'foo' if condition." I never missed having > that syntax in Python, but now that I have it in Ruby, > I use it quite often. > > 2) On a general note, Ruby is enough like Python > that it doesn't bend my brain. > > 3) I actually like being able to omit parentheses in > method definitions and method calls. In Ruby you can > express "add(3,5,7)" as both "add(3,5,7)" and "add 3, > 5, 7." The latter syntax is obviously more error > prone, but I don't think I've ever actually gotten bit > by it, and the code appears more clean to me. > > 4) Ruby forces you to explicitly make attributes for > instance variables. At first I found this clumsy, but > I've gotten used to it, and I actually kind of like it > in certain circumstances. > > What I miss about Python: > > 1) I like the fact that Python's syntax for passing > around methods is very natural. Ruby's syntax is much > more clumsy. > > 2) I miss indentation. I get bitten by kEnd in Ruby > all the time. > > 3) I miss Python's maturity. Just to give a small > example, Python's interpreter gives more readable > syntax error messages. > > Those are the things that jump out for me. I'm > curious to hear what other people have learned about > Python after maybe going away from it for a while. > > > > > > > > Be a better friend, newshound, and > know-it-all with Yahoo! Mobile. Try it now. > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ > > -- > http://mail.python.org/mailman/listinfo/python-list > -- http://search.goldwatches.com/?Search=Movado+Watches http://www.jewelerslounge.com http://www.goldwatches.com -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
Colin J. Williams wrote: > Steve Howell wrote:> > Thanks for the interesting comparison. > > [snip] > >> 3) I actually like being able to omit parentheses in >> method definitions and method calls. In Ruby you can >> express "add(3,5,7)" as both "add(3,5,7)" and "add 3, >> 5, 7." The latter syntax is obviously more error >> prone, but I don't think I've ever actually gotten bit >> by it, and the code appears more clean to me. >> >> > [snip] > > I'm not sure that I like add 3, 5, 7 > > but it would be nice to be able to drop > the parentheses > when no argument is required. > > Thus: close; > could replace close(); > > The fact that you can do this in Ruby and not in Python is why passing callables in Ruby is awkward and it's extremely natural in Python. In Ruby, of course, you don't pass callables around as much, using blocks instead, so it works out there. But it's an example of some of the fundamental syntax differences between the languages. -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
MonkeeSage wrote: > On Dec 7, 11:08 pm, Steve Howell <[EMAIL PROTECTED]> wrote: >> Python is my favorite programming language. I've used >> it as my primary language for about six years now, >> including four years of using it full-time in my day >> job. Three months ago I decided to take a position >> with a team that does a lot of things very well, but >> they don't use Python. We use Ruby instead. I'd like >> to share my observations about Ruby, because I think >> they say important things about Python, which has been >> my frame of reference. >> >> First of all, I actually enjoy programming in Ruby. >> Although I'm still fairly early on the learning curve, >> I feel like I've achieved basic fluency, and it >> generally stays out of the way. >> >> (A quick disclaimer is that some of the observations I >> make about Ruby may simply reflect my ignorance about >> the language. I'm still learning it.) >> >> The thing that I like least about Ruby is its >> "require" mechanism. Basically, when you do "require" >> in Ruby, it sort of pollutes your namespace. I much >> prefer Python's explicitness. >> >> Some surprising things that I like about Ruby: >> >> 1) It has the Perlish natural language syntax of >> "raise 'foo' if condition." I never missed having >> that syntax in Python, but now that I have it in Ruby, >> I use it quite often. This could be done in Python if raise became a function, as it has for print. Colin W. -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
Steve Howell wrote:> Thanks for the interesting comparison. [snip] > 3) I actually like being able to omit parentheses in > method definitions and method calls. In Ruby you can > express "add(3,5,7)" as both "add(3,5,7)" and "add 3, > 5, 7." The latter syntax is obviously more error > prone, but I don't think I've ever actually gotten bit > by it, and the code appears more clean to me. > [snip] I'm not sure that I like add 3, 5, 7 but it would be nice to be able to drop the parentheses when no argument is required. Thus: close; could replace close(); Colin W. -- http://mail.python.org/mailman/listinfo/python-list
Re: a Python person's experience with Ruby
On Dec 7, 11:08 pm, Steve Howell <[EMAIL PROTECTED]> wrote: > Python is my favorite programming language. I've used > it as my primary language for about six years now, > including four years of using it full-time in my day > job. Three months ago I decided to take a position > with a team that does a lot of things very well, but > they don't use Python. We use Ruby instead. I'd like > to share my observations about Ruby, because I think > they say important things about Python, which has been > my frame of reference. > > First of all, I actually enjoy programming in Ruby. > Although I'm still fairly early on the learning curve, > I feel like I've achieved basic fluency, and it > generally stays out of the way. > > (A quick disclaimer is that some of the observations I > make about Ruby may simply reflect my ignorance about > the language. I'm still learning it.) > > The thing that I like least about Ruby is its > "require" mechanism. Basically, when you do "require" > in Ruby, it sort of pollutes your namespace. I much > prefer Python's explicitness. > > Some surprising things that I like about Ruby: > > 1) It has the Perlish natural language syntax of > "raise 'foo' if condition." I never missed having > that syntax in Python, but now that I have it in Ruby, > I use it quite often. > > 2) On a general note, Ruby is enough like Python > that it doesn't bend my brain. > > 3) I actually like being able to omit parentheses in > method definitions and method calls. In Ruby you can > express "add(3,5,7)" as both "add(3,5,7)" and "add 3, > 5, 7." The latter syntax is obviously more error > prone, but I don't think I've ever actually gotten bit > by it, and the code appears more clean to me. > > 4) Ruby forces you to explicitly make attributes for > instance variables. At first I found this clumsy, but > I've gotten used to it, and I actually kind of like it > in certain circumstances. > > What I miss about Python: > > 1) I like the fact that Python's syntax for passing > around methods is very natural. Ruby's syntax is much > more clumsy. > > 2) I miss indentation. I get bitten by kEnd in Ruby > all the time. > > 3) I miss Python's maturity. Just to give a small > example, Python's interpreter gives more readable > syntax error messages. > > Those are the things that jump out for me. I'm > curious to hear what other people have learned about > Python after maybe going away from it for a while. > > > > Be a better friend, newshound, and > know-it-all with Yahoo! Mobile. Try it now. > http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ Hello, Standard disclaimer: This response is in the spirit of sharing knowledge and experience, as I take your post to be, not in the spirit of advocacy of any language. All opinions I express are simply that: my opinion. I use both python and ruby quite often. But I came from the other direction, starting with ruby then learning python. Overall, I think they are both great languages, and I believe the choice in whether to use one or the other (or both!) is determined mainly by expedience and preference. I'll try to give my thoughts on your points, which I had as I was learning python a few years ago, along with my current opinions: Ruby: 0.) I found python's concept of namespaces as defined by imported modules (i.e., files) to be strange at first. I used "from foo import *" a lot starting out. The main thing that I had to get my mind around was that in ruby a namespace applies to an object (even "main", i.e., toplevel, is an instance of class Object), and you can "re-open" objects to extend their namespace (or mix in "modules", which in ruby are like a container of unbound methods that you can "include" in another object and thereby bind those methods to that object). So rather than "import" a module with the namespace "string," as in python, in ruby you'd require a file that re-opens class String and extends it. They are two different approaches (and two different ideas of namespace pollution), but once you get your mind around both, they are very easy to use. I almost never use "from foo import *" now in python. 1.) I missed the infix version of conditionals that ruby provides at first, and I would often write things like "if foo: bar" in python if the line was short. Now it just feels more natural to write it on two lines in python most of the time, though in ruby I still use the other notation if the line is short. 2.) I found the same was true. I could basically translate 90% of the ruby idioms directly into python (minor syntax issues aside), and vise versa. 3.) I never have liked omitting parens in ruby method calls (with the exception of methods taking no arguments, but I didn't even do that for a long time), though many/most rubyists do use that style. One problem with it is that it leads to ambiguities, and the parser complains in thos
a Python person's experience with Ruby
Python is my favorite programming language. I've used it as my primary language for about six years now, including four years of using it full-time in my day job. Three months ago I decided to take a position with a team that does a lot of things very well, but they don't use Python. We use Ruby instead. I'd like to share my observations about Ruby, because I think they say important things about Python, which has been my frame of reference. First of all, I actually enjoy programming in Ruby. Although I'm still fairly early on the learning curve, I feel like I've achieved basic fluency, and it generally stays out of the way. (A quick disclaimer is that some of the observations I make about Ruby may simply reflect my ignorance about the language. I'm still learning it.) The thing that I like least about Ruby is its "require" mechanism. Basically, when you do "require" in Ruby, it sort of pollutes your namespace. I much prefer Python's explicitness. Some surprising things that I like about Ruby: 1) It has the Perlish natural language syntax of "raise 'foo' if condition." I never missed having that syntax in Python, but now that I have it in Ruby, I use it quite often. 2) On a general note, Ruby is enough like Python that it doesn't bend my brain. 3) I actually like being able to omit parentheses in method definitions and method calls. In Ruby you can express "add(3,5,7)" as both "add(3,5,7)" and "add 3, 5, 7." The latter syntax is obviously more error prone, but I don't think I've ever actually gotten bit by it, and the code appears more clean to me. 4) Ruby forces you to explicitly make attributes for instance variables. At first I found this clumsy, but I've gotten used to it, and I actually kind of like it in certain circumstances. What I miss about Python: 1) I like the fact that Python's syntax for passing around methods is very natural. Ruby's syntax is much more clumsy. 2) I miss indentation. I get bitten by kEnd in Ruby all the time. 3) I miss Python's maturity. Just to give a small example, Python's interpreter gives more readable syntax error messages. Those are the things that jump out for me. I'm curious to hear what other people have learned about Python after maybe going away from it for a while. Be a better friend, newshound, and know-it-all with Yahoo! Mobile. Try it now. http://mobile.yahoo.com/;_ylt=Ahu06i62sR8HDtDypao8Wcj9tAcJ -- http://mail.python.org/mailman/listinfo/python-list