[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

What does this statement do?

Stanislaw Wozniak

3/2/2009 2:03:00 PM

Hi Guys,

I have been wondering what does this statement do and what does it set.
It interferes with my methods_missing handler:

{code}
class MyClass

something = "something else"

end
{code}
--
Posted via http://www.ruby-....

6 Answers

Stanislaw Wozniak

3/2/2009 2:19:00 PM

0

Stanislaw Wozniak wrote:
> Hi Guys,
>
> I have been wondering what does this statement do and what does it set.
> It interferes with my methods_missing handler:
>
> {code}
> class MyClass
>
> something = "something else"
>
> end
> {code}

I guess this is assigning a string to a variable that is created in the
MyClass scope. But my problem is that I have some setter methods that
I'm using through method_missing, but method_missing is never triggered
because it is assigning stuff just like in the example above.
--
Posted via http://www.ruby-....

Tim Hunter

3/2/2009 2:23:00 PM

0

Stanislaw Wozniak wrote:
> Stanislaw Wozniak wrote:
>> Hi Guys,
>>
>> I have been wondering what does this statement do and what does it set.
>> It interferes with my methods_missing handler:
>>
>> {code}
>> class MyClass
>>
>> something = "something else"
>>
>> end
>> {code}
>
> I guess this is assigning a string to a variable that is created in the
> MyClass scope. But my problem is that I have some setter methods that
> I'm using through method_missing, but method_missing is never triggered
> because it is assigning stuff just like in the example above.

You're saying that "something" is supposed to be treated like a method
instead of like a variable? Try

self.something = "something else"

--
RMagick: http://rmagick.ruby...

Jason Roelofs

3/2/2009 2:27:00 PM

0

On Mon, Mar 2, 2009 at 9:18 AM, Stanislaw Wozniak <stan@wozniak.com> wrote:
> Stanislaw Wozniak wrote:
>> Hi Guys,
>>
>> I have been wondering what does this statement do and what does it set.
>> It interferes with my methods_missing handler:
>>
>> {code}
>> class MyClass
>>
>> =A0 =A0something =3D "something else"
>>
>> end
>> {code}
>
> I guess this is assigning a string to a variable that is created in the
> MyClass scope. But my problem is that I have some setter methods that
> I'm using through method_missing, but method_missing is never triggered
> because it is assigning stuff just like in the example above.
> --
> Posted via http://www.ruby-....
>
>

That statement is the same as calling MyClass.something=3D("something else"=
)

If you want method_missing to catch it, you need to define a
method_missing on the class itself, like this:

class MyClass

def self.method_missing(name, *args)
end

end

Jason

Stanislaw Wozniak

3/2/2009 2:31:00 PM

0

Ok, this is the example I want to get to work. Method set_field is never
triggered because local variable set_field is being set.

class A

def self.set_field=(value)
puts "Trying to set field value"
end

def method_missing(name, *args)
self.class.method(name).call args
end
def self.method_missing(name, *args)
new.method(name).call args
end

end

class B < A

def my_method(value)
set_field = value
end

end

B.my_method
--
Posted via http://www.ruby-....

Rick DeNatale

3/2/2009 2:52:00 PM

0

[Note: parts of this message were removed to make it a legal post.]

On Mon, Mar 2, 2009 at 9:31 AM, Stanislaw Wozniak <stan@wozniak.com> wrote:

> Ok, this is the example I want to get to work. Method set_field is never
> triggered because local variable set_field is being set.
>
> class A
>
> def self.set_field=(value)
> puts "Trying to set field value"
> end
>
> def method_missing(name, *args)
> self.class.method(name).call args
> end
> def self.method_missing(name, *args)
> new.method(name).call args
> end
>
> end
>
> class B < A
>
> def my_method(value)
> set_field = value
> end
>
> end
>
> B.my_method
>

Yes this is a well-known ruby newbie gotcha.

Because the Ruby syntax allows simple names to refer to either a local
variable or a method invocation, there are some times when things get
ambiguous.

In the case of a name on the right hand side of an assignment, or equivalent
settings, the ruby compiler treats the name as a local variable if the name
has already been assigned a value, and as a method call with an implied
receiver of self otherwise.

In the case of a name on the right hand side, it treats the name as a local
variable, and assigns it a value.

You HAVE to explicitly give a receiver of self when invoking an attribute
setter method in ruby. So in my_method you have to use self.set_field =
value.

And this is why, for those who like to mark methods as private.


class Foo

private
def a=(value)
...
end

def b
....
end

public
def c
self.a= 2 # This is okay
self.b # This triggers a NoMethodError "private method 'b'
called for ...
end
end
--
Rick DeNatale

Blog: http://talklikeaduck.denh...
Twitter: http://twitter.com/Ri...
WWR: http://www.workingwithrails.com/person/9021-ric...
LinkedIn: http://www.linkedin.com/in/ri...

Robert Klemme

3/2/2009 5:15:00 PM

0

On 02.03.2009 15:27, Jason Roelofs wrote:
> On Mon, Mar 2, 2009 at 9:18 AM, Stanislaw Wozniak <stan@wozniak.com> wrote:
>> Stanislaw Wozniak wrote:
>>> Hi Guys,
>>>
>>> I have been wondering what does this statement do and what does it set.
>>> It interferes with my methods_missing handler:
>>>
>>> {code}
>>> class MyClass
>>>
>>> something = "something else"
>>>
>>> end
>>> {code}
>> I guess this is assigning a string to a variable that is created in the
>> MyClass scope. But my problem is that I have some setter methods that
>> I'm using through method_missing, but method_missing is never triggered
>> because it is assigning stuff just like in the example above.
>> --
>> Posted via http://www.ruby-....
>>
>>
>
> That statement is the same as calling MyClass.something=("something else")

Actually, no. See Rick's excellent explanation. For test addicts:

[oracle@ora01 ~]$ ruby y.rb
test 1
foo called with 123
test 2
[oracle@ora01 ~]$ cat y.rb

class X
def self.foo=(a)
printf "foo called with %p\n", a
end
end

puts "test 1"
X.foo = 123

class X
puts "test 2"
foo = 987
end

[oracle@ora01 ~]$

> If you want method_missing to catch it, you need to define a
> method_missing on the class itself, like this:
>
> class MyClass
>
> def self.method_missing(name, *args)
> end
>
> end

Won't help here, because the statement is interpreted as a local
variable assignment.

Kind regards

robert