SitePoint Sponsor

User Tag List

Results 1 to 8 of 8

Hybrid View

  1. #1
    SitePoint Enthusiast
    Join Date
    Jan 2004
    Location
    Manchester
    Posts
    32
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Useful quirks in Ruby's syntax?

    Hi all

    I'm looking further into Ruby, and I'm wondering about case (switch) statements.

    In PHP, its possible to do the following:
    PHP Code:
    switch(true)
      {
          case 
    is_object($myvar):
          
    // do something
          
    break;
          case 
    is_array($myvar):
          
    // do something
           
    break;
          case 
    is_scalar($myvar):
          
    // do something
           
    break;
          default:
          break;
      } 
    So rather than evaluating case value against switch value, I'm evaluating case expression against switch value.

    Can I do the same in Ruby?

    Also, are there any other useful quirks in Ruby's syntax that people can take advantage of?

  2. #2
    SitePoint Zealot
    Join Date
    Nov 2004
    Location
    Yakima WA.
    Posts
    100
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:
    switch(true)
      {
          case 
    is_object($myvar):
          
    // do something
          
    break;
          case 
    is_array($myvar):
          
    // do something
           
    break;
          case 
    is_scalar($myvar):
          
    // do something
           
    break;
          default:
          break;
      } 

    Can I do the same in Ruby?
    I don't see the value in your switch(true) part of your statement. If you want to check for the type of object in a case statement in ruby you can do it this way:
    Code:
    case myvar
         when Array;    puts "Array"
         when String;   puts "String
         when Hash;     puts "Hash"
         when Fixnum;   puts "Fixnum
         # and so on ...
    end
    Or if you really want it to be like your php version you could do it this way:

    Code:
    case true
         when myvar.is_a? Array;    puts "Array"
         when myvar.is_a? String;   puts "String
         when myvar.is_a? Hash;     puts "Hash"
         when myvar.is_a? Fixnum;   puts "Fixnum
         # and so on ...
    end
    Is that what you mean to do? Also there are tons of little syntax tricks in ruby to learn. Maybe you can be more sspecific as to what you would like to see and I can try to accommodate? Also you may want to look here for more of the ruby idioms:

    http://www.rubygarden.org/ruby?RubyIdioms

    Cheers-
    -Ezra

  3. #3
    SitePoint Guru silver trophy Luke Redpath's Avatar
    Join Date
    Mar 2003
    Location
    London
    Posts
    794
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Incidentally, there might be a way of avoiding the case statement altogether - could you give a more concrete example of what you are trying to do, or is this purely hypothetical?

    I ask, because if there is an action that you need objects of several classes to do, but they need doing in slightly different ways depending on the object class, then it might be worth implementing a method ( say foo() ) for each object that encapsulates what you are doing, then simply calling myvar.foo().

    Switch/case statements or nested conditionals tend to be a bit smelly and are usually good candidates for refactoring, so I thought I'd ask.

  4. #4
    SitePoint Enthusiast
    Join Date
    Jan 2004
    Location
    Manchester
    Posts
    32
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Its all hypothetical. I'm just interested in new and interesting ways of using the syntax rather than patterns.

  5. #5
    SitePoint Guru silver trophy Luke Redpath's Avatar
    Join Date
    Mar 2003
    Location
    London
    Posts
    794
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by neobuddah
    Its all hypothetical. I'm just interested in new and interesting ways of using the syntax rather than patterns.
    I like use "and" to join to commands together on one line when it seems to make sense to do that, for example in some of my Rails functional tests:

    Code:
    login_as :admin and get :index
    I love it when Ruby starts reading like English, especially when writing test cases.

  6. #6
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by neobuddah

    Can I do the same in Ruby?
    Yes, although such constructs usually look quite silly
    Code:
    a = 1
    case true
    	when a == 1 then puts "one"
    	when a == 2 then puts "two"
    end

    Quote Originally Posted by neobuddah
    Also, are there any other useful quirks in Ruby's syntax that people can take advantage of?
    Ruby syntax is extremely flexible. Every trick you can think about is possible in ruby.

  7. #7
    SitePoint Enthusiast
    Join Date
    Jan 2004
    Location
    Manchester
    Posts
    32
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Code:
    login_as :admin and get :index
    What does this do? Coming from PHP, its quite difficult sometimes to understand which parts are syntax and which are method calls.

    I often do this in PHP classes:
    Code:
    private $this = null, $that = 0;
    How would I do this in Ruby?

  8. #8
    SitePoint Guru silver trophy Luke Redpath's Avatar
    Join Date
    Mar 2003
    Location
    London
    Posts
    794
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    In the above example login_as() and get() are method calls. Both take symbols as parameters admin and :index) and by taking advantage of Ruby's flexibility (no need to parenthesise method arguments in a lot of cases) and the ability to join two statements together using "and", you get the above.

    To do your example in ruby you would simply do:

    Code:
    this, that = nil, 0
    There is no need to declare instance variables as private as for all intents and purposes Ruby instance variables are always private (that is, you have to declare a getter/setter for an instance variable if you need read or write access). You can do that in two ways, using attr_reader, attr_writer and attr_accessor macros or manually if you need to do something more advanced.

    For example, if you have an object foo with an instance variable bar, you could do:

    Code:
    class FooClass
      attr_reader :bar
      # or for write access...
      # attr_writer :bar
      #
      # or for both...
      # attr_accessor :bar
    
      def initialize
        @bar = 'hello'
      end
    end
    attr_reader would create a getter method for @bar called bar(), attr_writer would create a setter method for @bar called bar=() and attr_accessor does both. Of course you could define these yourself:

    Code:
    class FooClass
      def initialize
        @bar = 'hello'
      end
    
      def bar()
        @bar
      end
    
      def bar=(attr)
        @bar = attr
      end
    end
    Either way you would use them as follows:

    Code:
    foo = FooClass.new
    puts foo.bar #=> 'hello'
    foo.bar = 'world'
    puts foo.bar #=> 'world'
    Note that in the above, doing:

    Code:
    foo.bar = 'something'
    is really just syntatic sugar and is the equivalent of the following:

    Code:
    foo.bar=('something')


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •