How to create "def method(item)= (value)"?

Hi, is it not possible to create a method to use in this way?

   my_object.param("tag") = "new_value"

How to define that method? I've tryed something as:

  def param(name)= (value)
    @params[name] = value
  end

but obviously I get error:

  SyntaxError: compile error
  syntax error, unexpected '='

Is there some way? Thanks a lot.

···

--
Iñaki Baz Castillo
<ibc@aliax.net>

Iñaki Baz Castillo wrote:

Hi, is it not possible to create a method to use in this way?

   my_object.param("tag") = "new_value"

How to define that method? I've tryed something as:

  def param(name)= (value)
    @params[name] = value
  end

but obviously I get error:

  SyntaxError: compile error
  syntax error, unexpected '='

Is there some way? Thanks a lot.

Untested, and probably highly inelegant:

def param key, value
~ @params["#{key.to_sym}"] = value
end

Should produce:

object.params my_key, 'my value'

=> @params[:my_key] => 'my value'

While not the interface you desire, it is the output you want.

(May be useful as a Rails helper, but otherwise?)

Or, you could use an optionhash to create your method:
,http://www.lukeredpath.co.uk/2006/7/27/using-ruby-hashes-as-keyword-arguments-with-easy-defaults&gt;

Something like:

def param(options = {})
~ @params[options.key] = options[options.key]
end

should look like

object.param 'key' => 'value'

=> @params['key'] => 'value'

You could sexy that up with Hash#merge:

def param(options = {})
~ @params = @params.merge options
end

(probably more efficient than the first variant, too.)

Hope that helps.

- --
Phillip Gawlowski
Twitter: twitter.com/cynicalryan
Blog: http://justarubyist.blogspot.com

~ - You know you've been hacking too long when...
...you want to wash your hair and think: awk -F"/neck" '{ print $1 }' |
shower

def initialize
  @params={}
end

def param
  @params
end

my_object.param["tag"]="new value"

If you need some sort of validation, you can have param return some other
class that defines and = and does the necessary validation, and you
can even set up an easy method for defining the param attribute to do all
of that if need be.

···

On Wed, 30 Apr 2008 07:22:30 -0500, Iñaki Baz Castillo wrote:

Hi, is it not possible to create a method to use in this way?

   my_object.param("tag") = "new_value"

How to define that method? I've tryed something as:

  def param(name)= (value)
    @params[name] = value
  end

but obviously I get error:

  SyntaxError: compile error
  syntax error, unexpected '='

Is there some way? Thanks a lot.

--
Ken (Chanoch) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/

Hi --

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Iñaki Baz Castillo wrote:
> Hi, is it not possible to create a method to use in this way?
>
> my_object.param("tag") = "new_value"
>
> How to define that method? I've tryed something as:
>
> def param(name)= (value)
> @params[name] = value
> end
>
> but obviously I get error:
>
> SyntaxError: compile error
> syntax error, unexpected '='
>
> Is there some way? Thanks a lot.
>

Untested, and probably highly inelegant:

def param key, value
~ @params["#{key.to_sym}"] = value
end

Should produce:

> object.params my_key, 'my value'
=> @params[:my_key] => 'my value'

"#{key.to_sym}" is always going to produce a string, never a symbol.
I'm not sure the OP wants to constrain the keys to be symbols anyway.
Also, you're calling params; I think you mean param.

So:

   def param(key,value)
     @params[key] = value
   end

   object.param(my_key, "my_value")

Also untested, due to laziness :slight_smile:

You could also do:

   def param=(key,value)
     @params[key] = value
   end

   object.param[key] = value

Of course, then one might as well do:

   attr_reader :params

on the object, and them:

   object.params[key] = value

David

···

On Wed, 30 Apr 2008, Phillip Gawlowski wrote:

--
Rails training from David A. Black and Ruby Power and Light:
   INTRO TO RAILS June 9-12 Berlin
   ADVANCING WITH RAILS June 16-19 Berlin
   INTRO TO RAILS June 24-27 London (Skills Matter)
See http://www.rubypal.com for details and updates!

Untested, and probably highly inelegant:

def param key, value
~ @params["#{key.to_sym}"] = value
end

Should produce:

> object.params my_key, 'my value'
=> @params[:my_key] => 'my value'

While not the interface you desire, it is the output you want.

Yes, that exactly what I do, but I don't like it, since it's not
intuitive. In fact I call the method "set_param(name, value)". But it
makes the code look like Java.. brrrrr.... XD

> object.param 'key' => 'value'
=> @params['key'] => 'value'

You could sexy that up with Hash#merge:

def param(options = {})
~ @params = @params.merge options
end

(probably more efficient than the first variant, too.)

Interesting, and thanks for the useful link. :slight_smile:

···

2008/4/30, Phillip Gawlowski <cmdjackryan@googlemail.com>:

--
Iñaki Baz Castillo
<ibc@aliax.net>

But I don't want that since it allows any self modification way
(.strip! .chomp! ...) and I just want to allow =

Thanks.

···

2008/4/30, Ken Bloom <kbloom@gmail.com>:

def initialize
  @params={}
end

def param
  @params
end

--
Iñaki Baz Castillo
<ibc@aliax.net>

David A. Black wrote:

> object.params my_key, 'my value'
=> @params[:my_key] => 'my value'

"#{key.to_sym}" is always going to produce a string, never a symbol.

*facepalm* Right. String interpolation. Too clever for my own good, is
what I am..

I'm not sure the OP wants to constrain the keys to be symbols anyway.

Well, given that Rails uses the params hash, with Symbols as keys, I
took a guess. :wink:

Also, it is a bit of a habit on my part to use Symbols, instead of
strings or so.

Also, you're calling params; I think you mean param.

Yes, indeed. Typo on my part (I cought it the other two chances..).

You could also do:

  def param=(key,value)
    @params[key] = value
  end

  object.param[key] = value

Oh, I'm gonna steal that idiom if you don't mind. :wink:

- --
Phillip Gawlowski
Twitter: twitter.com/cynicalryan
Blog: http://justarubyist.blogspot.com

~ "My ethicator machine must've had a built-in moral compromise
~ spectral release phantasmatron! I'm a genius!" --- Calvin

You could also do:

  def param=(key,value)
    @params[key] = value
  end

  object.param[key] = value

That's not valid, a method cannot contain :

def hola() end

SyntaxError: compile error
syntax error, unexpected '[', expecting '\n' or ';'
def hola() end

Of course, then one might as well do:

  attr_reader :params

on the object, and them:

  object.params[key] = value

Yes, but that is not valid for me since I need to exec some extra code
so I need to create an abstraction layer to access @params.

Thanks.

···

2008/4/30, David A. Black <dblack@rubypal.com>:

--
Iñaki Baz Castillo
<ibc@aliax.net>

Iñaki Baz Castillo wrote:

Yes, that exactly what I do, but I don't like it, since it's not
intuitive. In fact I call the method "set_param(name, value)". But it
makes the code look like Java.. brrrrr.... XD

Not commenting on the Java part (the naming in Java is usually rather
well done, IMO), but I agree, the solution isn't all too elegant because
of it's lack of intuitive assignment.

Usually, I use something like that, when I am too lazy to create an
optionhash based solution.

*adds that to TODO list for a current project*

Interesting, and thanks for the useful link. :slight_smile:

You are welcome. :slight_smile:

- --
Phillip Gawlowski
Twitter: twitter.com/cynicalryan
Blog: http://justarubyist.blogspot.com

Do you know why the fairy sits at the top of the Xmas tree ?

~ One year, Santa had one tree left over after giving everybody one, and
when one of his fairy helpers asked what she should do with it, he told her.

~ That`s why.

Why not just access param?

class Foo
  def initialize
    @param = {}
  end
  attr_accessor :param
end

x = Foo.new
x.param['key'] = 'bar'

If you do need to override it, the Hash assignment method is []=
So I think you can write:
def []=(key,value)
...

Cheers

In that case, do as I wrote further on and have the param function return
a proxy that edits the params array in only the ways you want.

class ParamsProxy
  def initialize hash
    #thanks to duck typing hash can be an Array instead, if you'd like
    @hash=hash
  end
  def key
    #with .dup here, mutating operations on the returned value
    #will not affect the values stored in the @hash
    #note that even attr_reader isn't this careful about the
    #objects that it returns, and so if you want behavior
    #like attr_reader, then omit the .dup here
    @hash[key].dup
  end
  def = key,value
    @hash[key]=value
  end
end

class MyClass
  def initialize
    @params={}
  end

  def param
    ParamsProxy.new @params
  end
end

I presented this in rough outline before, without code, because there are
many ways one could want to dress this up -- having some kind of
validation code, or having the object.param[key]=value update something
else entirely, or shoving the whole thing behind a nice attr_accessor-
like interface. I don't have the time now to think through all of the
possibilities involved to come up with a general solution, nor do I have
a clear idea of exactly what your other constraints are. But start here,
be creative, and let us know exactly what you do come up with.

--Ken

···

On Wed, 30 Apr 2008 09:56:04 -0500, Iñaki Baz Castillo wrote:

2008/4/30, Ken Bloom <kbloom@gmail.com>:

def initialize
  @params={}
end

def param
  @params
end

But I don't want that since it allows any self modification way (.strip!
.chomp! ...) and I just want to allow =

Thanks.

--
Ken (Chanoch) Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu/~kbloom1/

I'm sorry, but as I've replied in this thread that method naming
(using ) is invalid in Ruby :frowning:

···

2008/4/30, Phillip Gawlowski <cmdjackryan@googlemail.com>:

> You could also do:
>
> def param=(key,value)
> @params[key] = value
> end
>
> object.param[key] = value

Oh, I'm gonna steal that idiom if you don't mind. :wink:

--
Iñaki Baz Castillo
<ibc@aliax.net>

Because I need to give value to an attribute of a class containing the
Hash @params, so the only way (AFAIK) is by creating an abstraction
layer and handling the Hash @params via current class methods. This is
my case:

class Uri

  # Atributes:
  @modified => true/false
  @params => Hash

   attr_accessor :modified

   #what I want but it's not possible:
   def param(name)= (value)
      @params[name] = value
      @modified = true
   end

end

I can't do it by extending Hash class since inside Hash class I can't
modify @modified attribute.
Also note there are more ways than "=" to modify a Hash value:
  @params[name].strip! , .chomp! , .downcase! ......
and I don't want to redefine all of them so I just want to allow "="
and when it's called @modifed must be true.

Hope I've explained why attr_accessor is not useful for me in this case.

Thanks a lot.

···

2008/4/30, Chris Hulan <chris.hulan@gmail.com>:

Why not just access param?

class Foo
  def initialize
    @param = {}
  end
  attr_accessor :param
end

x = Foo.new
x.param['key'] = 'bar'

If you do need to override it, the Hash assignment method is =
So I think you can write:
def =(key,value)
...

--
Iñaki Baz Castillo
<ibc@aliax.net>

Hi --

···

On Wed, 30 Apr 2008, Iñaki Baz Castillo wrote:

2008/4/30, David A. Black <dblack@rubypal.com>:

You could also do:

  def param=(key,value)
    @params[key] = value
  end

  object.param[key] = value

That's not valid, a method cannot contain :

Yikes. Sorry. I'm being stupid. (I think there was some real code of
which that was a wrong version, but now I can't remember what I
meant....)

David

--
Rails training from David A. Black and Ruby Power and Light:
   INTRO TO RAILS June 9-12 Berlin
   ADVANCING WITH RAILS June 16-19 Berlin
   INTRO TO RAILS June 24-27 London (Skills Matter)
See http://www.rubypal.com for details and updates!

Hi --

> You could also do:
>
> def param=(key,value)
> @params[key] = value
> end
>
> object.param[key] = value

Oh, I'm gonna steal that idiom if you don't mind. :wink:

Sorry -- it's wrong. I think I've remembered what I meant to write.
This time, let's go all out and try the code! :slight_smile:

object = Object.new
class << object
   attr_accessor :params
end
object.params = {}

def object.=(key,value)
   @params[key] = value
end

object[1] = 2

p object.params # { 1 => 2 }

Too bad -- I kind of liked my garbled rubbish version :slight_smile:

David

···

On Wed, 30 Apr 2008, Phillip Gawlowski wrote:

--
Rails training from David A. Black and Ruby Power and Light:
   INTRO TO RAILS June 9-12 Berlin
   ADVANCING WITH RAILS June 16-19 Berlin
   INTRO TO RAILS June 24-27 London (Skills Matter)
See http://www.rubypal.com for details and updates!

Thanks a lot. Very useful information :slight_smile:

···

El Jueves, 1 de Mayo de 2008, Ken Bloom escribió:

On Wed, 30 Apr 2008 09:56:04 -0500, Iñaki Baz Castillo wrote:
> 2008/4/30, Ken Bloom <kbloom@gmail.com>:
>> def initialize
>> @params={}
>> end
>>
>> def param
>> @params
>> end
>
> But I don't want that since it allows any self modification way (.strip!
> .chomp! ...) and I just want to allow =
>
> Thanks.

In that case, do as I wrote further on and have the param function return
a proxy that edits the params array in only the ways you want.

class ParamsProxy
  def initialize hash
    #thanks to duck typing hash can be an Array instead, if you'd like
    @hash=hash
  end
  def key
    #with .dup here, mutating operations on the returned value
    #will not affect the values stored in the @hash
    #note that even attr_reader isn't this careful about the
    #objects that it returns, and so if you want behavior
    #like attr_reader, then omit the .dup here
    @hash[key].dup
  end
  def = key,value
    @hash[key]=value
  end
end

class MyClass
  def initialize
    @params={}
  end

  def param
    ParamsProxy.new @params
  end
end

I presented this in rough outline before, without code, because there are
many ways one could want to dress this up -- having some kind of
validation code, or having the object.param[key]=value update something
else entirely, or shoving the whole thing behind a nice attr_accessor-
like interface. I don't have the time now to think through all of the
possibilities involved to come up with a general solution, nor do I have
a clear idea of exactly what your other constraints are. But start here,
be creative, and let us know exactly what you do come up with.

--
Iñaki Baz Castillo

Iñaki Baz Castillo wrote:

> You could also do:
>
> def param=(key,value)
> @params[key] = value
> end
>
> object.param[key] = value

Oh, I'm gonna steal that idiom if you don't mind. :wink:

I'm sorry, but as I've replied in this thread that method naming
(using ) is invalid in Ruby :frowning:

Sort of. As a singleton method, you get the syntax error. But not if you
define as a method:

irb(main):001:0> def =(key,value)
irb(main):002:1> end
=> nil

- --
Phillip Gawlowski
Twitter: twitter.com/cynicalryan
Blog: http://justarubyist.blogspot.com

~ "It's great to have a friend who appreciates an earnest discussion of
ideas." -Calvin

···

2008/4/30, Phillip Gawlowski <cmdjackryan@googlemail.com>:

Oh, that seems really interesting, but unfortunatelly I can't
unerstand at all what yuo do there.
Specially I don't understand the meaning of first two lines:

  object = Object.new
  class << object

What does that "class" mean??

Thanks a lot.

···

2008/4/30, David A. Black <dblack@rubypal.com>:

object = Object.new
class << object
  attr_accessor :params
end
object.params = {}

def object.=(key,value)
  @params[key] = value
end

object[1] = 2

p object.params # { 1 => 2 }

--
Iñaki Baz Castillo
<ibc@aliax.net>

Create your own Hash subclass?

def MyBag

  def initialize(parent)
    @parent = parent
    @theBag = {}
  end

  def =(k,v)
    @theBag[k] = v
    @parent.modified = true
  end

  def (k)
    @theBag[k]
  end
end

class Uri
  def initialize
    @params = MyBag.new(self) #need to do this in initialize,
otherwise self is not the instance
    @modified = false
  end
  attr_accessor :modified, :params

end

Not tested, and there is most likely a more elegant way to delegate to
Hash, but you get what you pay for 9^)

···

On Apr 30, 9:40 am, Iñaki Baz Castillo <i...@aliax.net> wrote:

2008/4/30, Chris Hulan <chris.hu...@gmail.com>:

> Why not just access param?

> class Foo
> def initialize
> @param = {}
> end
> attr_accessor :param
> end

> x = Foo.new
> x.param['key'] = 'bar'

> If you do need to override it, the Hash assignment method is =
> So I think you can write:
> def =(key,value)
> ...

Because I need to give value to an attribute of a class containing the
Hash @params, so the only way (AFAIK) is by creating an abstraction
layer and handling the Hash @params via current class methods. This is
my case:

class Uri

  # Atributes:
  @modified => true/false
  @params => Hash

   attr_accessor :modified

   #what I want but it's not possible:
   def param(name)= (value)
      @params[name] = value
      @modified = true
   end

end

I can't do it by extending Hash class since inside Hash class I can't
modify @modified attribute.
Also note there are more ways than "=" to modify a Hash value:
  @params[name].strip! , .chomp! , .downcase! ......
and I don't want to redefine all of them so I just want to allow "="
and when it's called @modifed must be true.

Hope I've explained why attr_accessor is not useful for me in this case.

Thanks a lot.

--
Iñaki Baz Castillo
<i...@aliax.net>

Yes, but I need "def some_name" :slight_smile:

···

2008/4/30, Phillip Gawlowski <cmdjackryan@googlemail.com>:

Sort of. As a singleton method, you get the syntax error. But not if you
define as a method:

irb(main):001:0> def =(key,value)
irb(main):002:1> end
=> nil

--
Iñaki Baz Castillo
<ibc@aliax.net>