Good writing in Ruby

I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Depending upon a variable 'user.role',
I would like to suppress all elements in the array , less or equal to this variable

ex :
user.role = "a" #=> roles = ["b", "c", "d", "e" ] "a" deleted
user.role = "b" #=> roles = ["c", "d", "e" ] "a", "b" deleted
user.role = "c" #=> roles = [ "d", "e" ] "a", "b", "c" deleted
user.role = "d" #=> roles = [ "e" ] "a", "b", "c", "d" deleted
user.role = "e" # do nothing

thanks for your tips

Joss
(I am on my way to buy the Ruby Recipes PDF Cookbook...)

I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Depending upon a variable 'user.role',
I would like to suppress all elements in the array , less or equal to this variable

ex :
user.role = "a" #=> roles = ["b", "c", "d", "e" ] "a" deleted
user.role = "b" #=> roles = ["c", "d", "e" ] "a", "b" deleted
user.role = "c" #=> roles = [ "d", "e" ] "a", "b", "c" deleted
user.role = "d" #=> roles = [ "e" ] "a", "b", "c", "d" deleted
user.role = "e" # do nothing

thanks for your tips

Joss
(I am on my way to buy the Ruby Recipes PDF Cookbook...)

Do you actually want to modify the array or do you just want to work with the reduced set? Does this help?

>> roles = %w{a b c d e f}
=> ["a", "b", "c", "d", "e", "f"]
>> roles.select {|r| r >= "c"}
=> ["c", "d", "e", "f"]
>> roles.select {|r| r > "c"}
=> ["d", "e", "f"]
>> roles
=> ["a", "b", "c", "d", "e", "f"]
>> roles.delete_if {|r| r <= "c"}
=> ["d", "e", "f"]
>> roles
=> ["d", "e", "f"]

Kind regards

  robert

···

On 10.08.2006 18:17, Josselin wrote:

I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Depending upon a variable 'user.role',
I would like to suppress all elements in the array , less or equal to this variable

ex :
user.role = "a" #=> roles = ["b", "c", "d", "e" ] "a" deleted
user.role = "b" #=> roles = ["c", "d", "e" ] "a", "b" deleted
user.role = "c" #=> roles = [ "d", "e" ] "a", "b", "c" deleted
user.role = "d" #=> roles = [ "e" ] "a", "b", "c", "d" deleted
user.role = "e" # do nothing

Maybe...

roles = roles.map {|x| x <= user.role ? x : nil }.compact

haven't tested it though...

Depending upon a variable 'user.role',
I would like to suppress all elements in the array , less or equal to this variable

ex :
user.role = "a" #=> roles = ["b", "c", "d", "e" ] "a" deleted
user.role = "b" #=> roles = ["c", "d", "e" ] "a", "b" deleted
user.role = "c" #=> roles = [ "d", "e" ] "a", "b", "c" deleted
user.role = "d" #=> roles = [ "e" ] "a", "b", "c", "d" deleted
user.role = "e" # do nothing

See if this gives you some ideas:

>> class User
>> def initialize
>> @roles = %w[a b c d e]
>> @role = nil
>> end
>>
?> attr_accessor :role
>>
?> def roles
>> return @roles if @role.nil? or not (i = @roles.index(@role))
>>
?> @roles[0...i]
>> end
>> end
=> nil
>> user = User.new
=> #<User:0x322b00 @role=nil, @roles=["a", "b", "c", "d", "e"]>
>> user.roles
=> ["a", "b", "c", "d", "e"]
>> user.role = "c"
=> "c"
>> user.roles
=> ["a", "b"]

James Edward Gray II

···

On Aug 10, 2006, at 11:20 AM, Josselin wrote:

Some more infos about what are the relations among the User class and
the roles array would be nice.

Anyway you can easily rewrite your role= method of the User class to
something like this

def role=(value, array)
    self.role = array.delete value if array.member? value
end

or, if you are happy to end up with a role of nil in case the role is
invalid/already given away

def role=(value, array)
  self.role = array.delete value
end

···

On 10/08/06, Josselin <josselin@wanadoo.fr> wrote:

I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Depending upon a variable 'user.role',
I would like to suppress all elements in the array , less or equal to
this variable

ex :
user.role = "a" #=> roles = ["b", "c", "d", "e" ] "a" deleted
user.role = "b" #=> roles = ["c", "d", "e" ] "a", "b" deleted
user.role = "c" #=> roles = [ "d", "e" ] "a", "b", "c" deleted
user.role = "d" #=> roles = [ "e" ] "a", "b", "c", "d" deleted
user.role = "e" # do nothing

thanks for your tips

Joss
(I am on my way to buy the Ruby Recipes PDF Cookbook...)

Josselin wrote:

I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Depending upon a variable 'user.role',
I would like to suppress all elements in the array , less or equal to this variable

ex :
user.role = "a" #=> roles = ["b", "c", "d", "e" ] "a" deleted
user.role = "b" #=> roles = ["c", "d", "e" ] "a", "b" deleted
user.role = "c" #=> roles = [ "d", "e" ] "a", "b", "c" deleted
user.role = "d" #=> roles = [ "e" ] "a", "b", "c", "d" deleted
user.role = "e" # do nothing

I'm not quite sure I understand your problem. Is this what you're looking for?

   roles = %w{a b c d e}
   user.role = "c"

   # non-destructive:
   roles.select{|role| role > user.role } #=> ["d", "e"]
   roles #=> ["a", "b", "c", "d", "e"]

   # destructive:
   roles.delete_if{|role| role <= user.role }
   roles #=> ["d", "e"]

Cheers,
Daniel

Do the "roles" have to be those letters, or did you just use them to
illustrate what you're doing? If you can use numbers for "roles"
instead, a whole new realm of possibilities opens up using comparison
operators.

···

On Fri, Aug 11, 2006 at 01:20:08AM +0900, Josselin wrote:

I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

--
CCD CopyWrite Chad Perrin [ http://ccd.apotheon.org ]
Ben Franklin: "As we enjoy great Advantages from the Inventions of
others we should be glad of an Opportunity to serve others by any
Invention of ours, and this we should do freely and generously."

Chad Perrin wrote:

···

On Fri, Aug 11, 2006 at 01:20:08AM +0900, Josselin wrote:

I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Do the "roles" have to be those letters, or did you just use them to
illustrate what you're doing? If you can use numbers for "roles"
instead, a whole new realm of possibilities opens up using comparison
operators.

Actually,

   "b" > "a" => true
   "a" < "b" => true
   "a" <=> "b" => -1

Cheers,
Daniel

yeah see my answer to Daniel... I believe adding an integer priority field will be easier (sure.. if I need to add new roles later...)
thanks

···

On 2006-08-10 22:01:38 +0200, Chad Perrin <perrin@apotheon.com> said:

On Fri, Aug 11, 2006 at 01:20:08AM +0900, Josselin wrote:

I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Do the "roles" have to be those letters, or did you just use them to
illustrate what you're doing? If you can use numbers for "roles"
instead, a whole new realm of possibilities opens up using comparison
operators.

in this particular case, 'roles' array is built from the table 'roles',
all values are possible roles for a new user so I don't modify the database
this 'roles' array is presented as select options,

'roles' array content is based on current_user.role
if current_user.role is 'god' then all collection (he can CRUD any role) is presented
if current_user.role is 'admin' then all collection minus 'god' and 'admin' (an admin cannot create god users or admini users)....

thanks

···

On 2006-08-10 18:37:18 +0200, "Paolo Negri" <hungrylist@gmail.com> said:

Some more infos about what are the relations among the User class and
the roles array would be nice.

Anyway you can easily rewrite your role= method of the User class to
something like this

def role=(value, array)
    self.role = array.delete value if array.member? value
end

or, if you are happy to end up with a role of nil in case the role is
invalid/already given away

def role=(value, array)
  self.role = array.delete value
end

On 10/08/06, Josselin <josselin@wanadoo.fr> wrote:

I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Depending upon a variable 'user.role',
I would like to suppress all elements in the array , less or equal to
this variable

ex :
user.role = "a" #=> roles = ["b", "c", "d", "e" ] "a" deleted
user.role = "b" #=> roles = ["c", "d", "e" ] "a", "b" deleted
user.role = "c" #=> roles = [ "d", "e" ] "a", "b", "c" deleted
user.role = "d" #=> roles = [ "e" ] "a", "b", "c", "d" deleted
user.role = "e" # do nothing

thanks for your tips

Joss
(I am on my way to buy the Ruby Recipes PDF Cookbook...)

I'll test it, values in array are strings : 'god', 'administrator', ''manager', 'owner', 'customer'
exclusion is based on a prority order
if current_user role is 'god' then exclude 'god' (there can be only one god)
if current_user role is 'administrator' then exclude 'god' and 'administrator'
if current_user role is 'manager' then exclude 'god' and 'administrator' and 'manager'
if current_user role is 'owner' then exclude 'god' and 'administrator' and 'manager' and 'owner'
...
as roles could change in the future (and also ro avoid possible localization issues) I believe it would be better to work with an additional integer priority field in the 'role' table, so I can sort the collection on priority and get a sorted roles array whatever is in the table...
thanks

···

On 2006-08-10 18:25:19 +0200, Philip Hallstrom <ruby@philip.pjkh.com> said:

I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Depending upon a variable 'user.role',
I would like to suppress all elements in the array , less or equal to this variable

ex :
user.role = "a" #=> roles = ["b", "c", "d", "e" ] "a" deleted
user.role = "b" #=> roles = ["c", "d", "e" ] "a", "b" deleted
user.role = "c" #=> roles = [ "d", "e" ] "a", "b", "c" deleted
user.role = "d" #=> roles = [ "e" ] "a", "b", "c", "d" deleted
user.role = "e" # do nothing

Maybe...

roles = roles.map {|x| x <= user.role ? x : nil }.compact

haven't tested it though...

thanks I'll look over it .. I'll check how it works with string values

···

On 2006-08-10 18:22:50 +0200, Robert Klemme <shortcutter@googlemail.com> said:

On 10.08.2006 18:17, Josselin wrote:

I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Depending upon a variable 'user.role',
I would like to suppress all elements in the array , less or equal to this variable

ex :
user.role = "a" #=> roles = ["b", "c", "d", "e" ] "a" deleted
user.role = "b" #=> roles = ["c", "d", "e" ] "a", "b" deleted
user.role = "c" #=> roles = [ "d", "e" ] "a", "b", "c" deleted
user.role = "d" #=> roles = [ "e" ] "a", "b", "c", "d" deleted
user.role = "e" # do nothing

thanks for your tips

Joss
(I am on my way to buy the Ruby Recipes PDF Cookbook...)

Do you actually want to modify the array or do you just want to work with the reduced set? Does this help?

>> roles = %w{a b c d e f}
=> ["a", "b", "c", "d", "e", "f"]
>> roles.select {|r| r >= "c"}
=> ["c", "d", "e", "f"]
>> roles.select {|r| r > "c"}
=> ["d", "e", "f"]
>> roles
=> ["a", "b", "c", "d", "e", "f"]
>> roles.delete_if {|r| r <= "c"}
=> ["d", "e", "f"]
>> roles
=> ["d", "e", "f"]

Kind regards

  robert

Silly me, I forgot Ruby did that.

···

On Fri, Aug 11, 2006 at 06:00:13AM +0900, Daniel Schierbeck wrote:

Actually,

  "b" > "a" => true
  "a" < "b" => true
  "a" <=> "b" => -1

--
CCD CopyWrite Chad Perrin [ http://ccd.apotheon.org ]
"It's just incredible that a trillion-synapse computer could actually
spend Saturday afternoon watching a football game." - Marvin Minsky

no, it was just for illustration.... roles are full string names...
'god' 'administrator' 'manager', 'owner', 'customer'
Initially I thought using an additional integer field as a 'priority'
'god' priority > 'administrator' priority > etc....

the objective is presenting a collection for select option depending upon the current_user role
if 'god' then all collection (he can CRUD any role)
if 'admin' then all collection - 'god' and 'admin'
.....

···

On 2006-08-10 22:56:32 +0200, Daniel Schierbeck <daniel.schierbeck@gmail.com> said:

Chad Perrin wrote:

On Fri, Aug 11, 2006 at 01:20:08AM +0900, Josselin wrote:

I know I can write it the 'ugly common way' (loop)
but I'd like to see how it can be done the Ruby way ... (I am a newbie...)

here is an array
roles = [ "a", "b", "c", "d", "e" ]

Do the "roles" have to be those letters, or did you just use them to
illustrate what you're doing? If you can use numbers for "roles"
instead, a whole new realm of possibilities opens up using comparison
operators.

Actually,

   "b" > "a" => true
   "a" < "b" => true
   "a" <=> "b" => -1

Cheers,
Daniel

You could make a Role class, define a <=> operator and mix in Comparable.

martin

···

On 8/11/06, Josselin <josselin@wanadoo.fr> wrote:

On 2006-08-10 22:01:38 +0200, Chad Perrin <perrin@apotheon.com> said:

> On Fri, Aug 11, 2006 at 01:20:08AM +0900, Josselin wrote:
>> I know I can write it the 'ugly common way' (loop)
>> but I'd like to see how it can be done the Ruby way ... (I am a newbie...)
>>
>> here is an array
>> roles = [ "a", "b", "c", "d", "e" ]
>
> Do the "roles" have to be those letters, or did you just use them to
> illustrate what you're doing? If you can use numbers for "roles"
> instead, a whole new realm of possibilities opens up using comparison
> operators.

yeah see my answer to Daniel... I believe adding an integer priority
field will be easier (sure.. if I need to add new roles later...)
thanks

Josselin wrote:

<snip>
I'll test it, values in array are strings : 'god', 'administrator', ''manager', 'owner', 'customer'
exclusion is based on a prority order
if current_user role is 'god' then exclude 'god' (there can be only one god)

It's a monotheistic system then? :wink:

-Justin

Hi --

···

On Sat, 12 Aug 2006, Justin Collins wrote:

Josselin wrote:

<snip>
I'll test it, values in array are strings : 'god', 'administrator', ''manager', 'owner', 'customer'
exclusion is based on a prority order
if current_user role is 'god' then exclude 'god' (there can be only one god)

It's a monotheistic system then? :wink:

But the customer is always right :slight_smile:

David

--
http://www.rubypowerandlight.com => Ruby/Rails training & consultancy
   ----> SEE SPECIAL DEAL FOR RUBY/RAILS USERS GROUPS! <-----
http://dablog.rubypal.com => D[avid ]A[. ]B[lack's][ Web]log
Ruby for Rails => book, Ruby for Rails
http://www.rubycentral.org => Ruby Central, Inc.

thanks Martin, that's what I finally did... writing my own Role class (the original one was part of an authorization plugin... did not have some much control over it )

joss

···

On 2006-08-11 08:39:25 +0200, "Martin DeMello" <martindemello@gmail.com> said:

On 8/11/06, Josselin <josselin@wanadoo.fr> wrote:

On 2006-08-10 22:01:38 +0200, Chad Perrin <perrin@apotheon.com> said:

> On Fri, Aug 11, 2006 at 01:20:08AM +0900, Josselin wrote:
>> I know I can write it the 'ugly common way' (loop)
>> but I'd like to see how it can be done the Ruby way ... (I am a newbie...)
>>
>> here is an array
>> roles = [ "a", "b", "c", "d", "e" ]
>
> Do the "roles" have to be those letters, or did you just use them to
> illustrate what you're doing? If you can use numbers for "roles"
> instead, a whole new realm of possibilities opens up using comparison
> operators.

yeah see my answer to Daniel... I believe adding an integer priority
field will be easier (sure.. if I need to add new roles later...)
thanks

You could make a Role class, define a <=> operator and mix in Comparable.

martin