Модераторы: korob2001, ginnie

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как определить, объект нам передали, Опрделение приведенности к чему либо... 
V
    Опции темы
Nab
Дата 4.2.2007, 17:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 582
Регистрация: 25.3.2006
Где: Kiev

Репутация: 26
Всего: 37



Вот затрудняюсь с таким вопросом...

Если мне в функцию передают ссылку, как универсально определить что она приведена к какому нибудь классу (пакету)?

Я имею несколько вариантов, но они мне не очень нравиться... мож есть что получше, или пакет какой имеется?

первый вариант таков:
Код

if (ref $param and $param =/(\w+)\=\(/) { print "$param объект приведенный к классу $1" }


можно еще проверять на принадлежность ссылки к известным типам, вот так примерно:
Кстати я не уверен что перечислил все типы ссылок smile
Код

if (ref $param ne 'SCALAR' and 
    ref $param ne 'HASH' and 
    ref $param ne 'ARRAY' and 
    ref $param ne 'CODE' and 
    ref $param ne 'GLOB' ) 
{ print "Ok"}


но такой метод не сработает если найдется еще один тип который появиться в следующей версии, да и вообще не верно это...

можно еще вот так:
Код

eval "$param->isa('UNIVERSAL')";
print "$param is object" unless $@;

но это тоже не самое элегантное решение smile

Вот предлагайте свои варианты....


--------------------
 Чтобы правильно задать вопрос нужно знать больше половины ответа...
Perl Community 
FREESCO in Ukraine 
PM MAIL   Вверх
Zuzu
Дата 5.2.2007, 11:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 140
Регистрация: 19.10.2006
Где: Екатеринбург

Репутация: 3
Всего: 4



Цитата(Nab @  4.2.2007,  20:00 Найти цитируемый пост)
Если мне в функцию передают ссылку, как универсально определить что она приведена к какому нибудь классу (пакету)?


perldoc -f ref

Код

...
   SCALAR
    ARRAY
    HASH
    CODE
    REF
    GLOB
    LVALUE
...
If the referenced object has been blessed into a package, then that package name is returned instead.


Если ref() вернула что-то вразумительное и этого нет в списке - то ссылка приведена к пакету. 


Это сообщение отредактировал(а) Zuzu - 5.2.2007, 11:25
--------------------
Проводить эксперименты на живом сервере опасно, а на мертвом - бесполезно.
PM   Вверх
nitr
Дата 5.2.2007, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2543
Регистрация: 10.2.2006
Где: Россия :)

Репутация: 37
Всего: 84



Zuzu, имхо он указал такую возможность:
Цитата(Nab @  4.2.2007,  17:00 Найти цитируемый пост)
Кстати я не уверен что перечислил все типы ссылок smile

if (ref $param ne 'SCALAR' and     
ref $param ne 'HASH' and     
ref $param ne 'ARRAY' and     
ref $param ne 'CODE' and    
ref $param ne 'GLOB' ) { 
print "Ok"
}

но такой метод не сработает если найдется еще один тип который появиться в следующей версии, да и вообще не верно это...

и почему не подходит

Похоже вариант
Цитата(Nab @  4.2.2007,  17:00 Найти цитируемый пост)
можно еще вот так:

eval "$param->isa('UNIVERSAL')";print "$param is object" unless $@;

но это тоже не самое элегантное решение smile

более подходящий, но вот о скорости вопрос...

Да и может такие модули помогут
Class::Inspector
Class::ISA

Я лично воспользовался бы 
Код

if (ref $param and $param =~ /=/ ) { print 'Is '.(ref $param) }


Добавлено @ 13:58 
или smile
Код

if (ref $param and index($param, '=') > 0 ) { ... }


Это сообщение отредактировал(а) nitr - 5.2.2007, 14:01


--------------------
PM   Вверх
Shaggie
Дата 5.2.2007, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 570
Регистрация: 21.12.2006
Где: outer space

Репутация: нет
Всего: 72



nitr, причем здесь = smile 


--------------------
Цитата(alina3000 @  6.3.2014,  10:47 Найти цитируемый пост)
Сорри что не по теме 
PM MAIL ICQ GTalk Jabber   Вверх
nitr
Дата 5.2.2007, 14:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2543
Регистрация: 10.2.2006
Где: Россия :)

Репутация: 37
Всего: 84



Shaggie, 
ну если верно понял вопрос то вот smile
Код

#!perl
use CGI;

my $param = CGI->new;
print $param;



--------------------
PM   Вверх
Nab
Дата 5.2.2007, 14:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 582
Регистрация: 25.3.2006
Где: Kiev

Репутация: 26
Всего: 37



Цитата(nitr @  5.2.2007,  13:57 Найти цитируемый пост)
Я лично воспользовался бы 
Код

if (ref $param and $param =~ /=/ ) { print 'Is '.(ref $param) }

Ну сейчас вот почти такой вариант и стоит smile
Код

if (ref $param and $param =~ /\w+\=\(/ ) 

Я просто немного жестче задал условие.


Цитата(Shaggie @  5.2.2007,  14:09 Найти цитируемый пост)
 nitr, причем здесь = smile 

Ну я за nitr'а отвечу smile

Потому что если сделать ссылке на объект просто:
Код

print $param

то получим что-то вродк вот такого:
Код

main=HASH(0x15d4f78)

Символ '=' там есть именно когда ссылка приведена к чему либо...
Попробуйте...
Код

my $obj = bless {};
print $obj;




--------------------
 Чтобы правильно задать вопрос нужно знать больше половины ответа...
Perl Community 
FREESCO in Ukraine 
PM MAIL   Вверх
Shaggie
Дата 5.2.2007, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 570
Регистрация: 21.12.2006
Где: outer space

Репутация: нет
Всего: 72



Код

package qwerty;

sub new {
    my $check = shift;
    my $class = ref($check) || $check;
    my $self = {};
    return bless( $self, $class );
}

package main;

my $obj = new qwerty;
print ref $obj;

Никакого = нету. Что делать? Применять способ Zuzu.
Или я что-то неправильно делаю smile 


--------------------
Цитата(alina3000 @  6.3.2014,  10:47 Найти цитируемый пост)
Сорри что не по теме 
PM MAIL ICQ GTalk Jabber   Вверх
nitr
Дата 5.2.2007, 14:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2543
Регистрация: 10.2.2006
Где: Россия :)

Репутация: 37
Всего: 84



Цитата(Nab @  5.2.2007,  14:19 Найти цитируемый пост)
Я просто немного жестче задал условие.

а надо? smile имхо чем быстрее тем лучше надо чтоб протестили скорость с index
Идея одна smile

Nab,  я тоже ответил тут smile

Добавлено @ 14:24 
Shaggie, print ref $obj;

измени на print $obj;

з.ы.: Shaggie, чуть внимательней...

Это сообщение отредактировал(а) nitr - 5.2.2007, 14:25


--------------------
PM   Вверх
Shaggie
Дата 5.2.2007, 14:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 570
Регистрация: 21.12.2006
Где: outer space

Репутация: нет
Всего: 72



Цитата(nitr @  5.2.2007,  14:22 Найти цитируемый пост)
смотри внимательно

Оппаньки, и в самом деле... Даже не подозревал... smile 


--------------------
Цитата(alina3000 @  6.3.2014,  10:47 Найти цитируемый пост)
Сорри что не по теме 
PM MAIL ICQ GTalk Jabber   Вверх
Nab
Дата 5.2.2007, 14:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 582
Регистрация: 25.3.2006
Где: Kiev

Репутация: 26
Всего: 37



Ок, спасибо всем участвовашим, Zuzu, персонально, ткнул носом в доку smile

Но скорее всего я оставлю свой вариант, считаю его самым универсальным...


--------------------
 Чтобы правильно задать вопрос нужно знать больше половины ответа...
Perl Community 
FREESCO in Ukraine 
PM MAIL   Вверх
Zuzu
Дата 5.2.2007, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 140
Регистрация: 19.10.2006
Где: Екатеринбург

Репутация: 3
Всего: 4



Nab, можно еще покопаться в коде модуля Data::Dumper - он пишет, что "ссылка приведена". Может там какое-то интересное решение есть. Пишет ведь, к какому пакету приведена ссылка!

Код

#!/use/bin/perl

use CGI;

my $cgi = new CGI;
use Data::Dumper;
print Dumper($cgi);


Результат:

Код

$VAR1 = bless( {
                 '.charset' => 'ISO-8859-1',
                 '.parameters' => [],
                 '.fieldnames' => {}
               }, 'CGI' );


--------------------
Проводить эксперименты на живом сервере опасно, а на мертвом - бесполезно.
PM   Вверх
nitr
Дата 5.2.2007, 15:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 2543
Регистрация: 10.2.2006
Где: Россия :)

Репутация: 37
Всего: 84



Scalar::Util::blessed
Цитата

sub UNIVERSAL::a_sub_not_likely_to_be_here { ref($_[0]) }

sub blessed ($) {
  local($@, $SIG{__DIE__}, $SIG{__WARN__});
  length(ref($_[0]))
    ? eval { $_[0]->a_sub_not_likely_to_be_here }
    : undef
}



--------------------
PM   Вверх
Nab
Дата 9.2.2007, 17:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 582
Регистрация: 25.3.2006
Где: Kiev

Репутация: 26
Всего: 37



Всетаки итог подвести надо...

В Dumper и Scalar::Util реализованы варианты тех методов что и я предлагал, тока еще более извращенно smile


nitr, спасибо напомнил про Scalar::Util. Дело в том что я его усиленно уюзаю, но только одну функцию, а именно weaken для отвязки от зацикливания. Про blessed я читал, когда осваивал этот модуль, просто вылетело из головы...


И еще раз спасибо всем, участвовамшим в обсуждении... помогли хоть как-то определиться...


--------------------
 Чтобы правильно задать вопрос нужно знать больше половины ответа...
Perl Community 
FREESCO in Ukraine 
PM MAIL   Вверх
tishaishii
Дата 11.2.2007, 08:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Создатель
***


Профиль
Группа: Завсегдатай
Сообщений: 1262
Регистрация: 14.2.2006
Где: Москва

Репутация: 4
Всего: 8



Быстрее:
Код

sub UNIVERSAL::a_sub_not_likely_to_be_here{}

sub blessed {+&UNIVERSAL::can(shift, 'a_sub_not_likely_to_be_here')}

PM MAIL ICQ Skype   Вверх
Nab
Дата 11.2.2007, 12:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 582
Регистрация: 25.3.2006
Где: Kiev

Репутация: 26
Всего: 37



tishaishii, молодец, реально лучший вариант, получай плюс от меня smile 

Но я вот подумал, что a_sub_not_likely_to_be_here добавляется чтоб его проверить, но ведь начиная с какой то версии Perl, класс UNIVERSAL содержит минимум два метода (can, isa), можно ведь проверять их...

Вот что у меня получилось:
Код

sub blessed {&UNIVERSAL::can(shift, 'isa')}


Проверил, вроде работает... да, рановато я тему закрыл smile


PS: кстати, tishaishii, вопрос, не могу до конца въехать в этот плюсик что у тебя в коде встречаю... не разъяснишь подробней, плиз...
Тока не отсылайте читать документацию, я ее прочел, меня интересует больше обоснованность такого постоянного употребления, большинство кода работает и без него подозреваю...


--------------------
 Чтобы правильно задать вопрос нужно знать больше половины ответа...
Perl Community 
FREESCO in Ukraine 
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1389 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.